图论中的0x3f和memset使用注意事项(较详细)

article/2025/9/23 15:08:18

图论中的memset0x3f

写此博客的背景

相信有很多同学在看别人图论专题的题解、板子的时候经常看到下面两句:

const int INF = 0x3f3f3f3f;
memset(d, INF, sizeof(d));

或者下面这样:

memset(d, 0x3f, sizeof(d));

很多同学都不明所以,只知道是将d数组中的所有元素初始化成INF,但是至于为什么选用0x3f3f3f3f和函数memset的原理都不清楚,看到别人这样用,自己也这样用,不清楚为什么,于是前几天同学来问我的时候,就出现了以下WA的代码片段:

const int INF = 1e5// ...
memset(d, INF, sizeof(d));

以及:

const int INF = 0x3f3f3f3f;	
// ...
memset(a, INF, sizeof(a));
memset(b, INF, sizeof(b));
// ...
ans = min(ans, a[i][k] + a[k][j] + b[i][j]);

如果清楚了上面两个问题,这些bug就可以避免。故写此篇博客,讲解下0x3f3f3f3fmemset的原理和使用注意事项。

memset的原理

C++API文档中的解释与函数原型
C++API截图-memset函数
可以看到该函数本身是用来初始化字符串(该函数位于string.h中,为C语言头文件,故这里的字符串即char数组,而不是C++中的string),但是参数列表中的第一个参数为void*,再加上C语言的一些特性,该函数也可以对其他类型的数组进行初始化,但是会存在一些其他的问题,下面进行说明。

我们知道在C语言中,char类型占1个字节,而int类型占4个字节。memset在对字符串进行初始化时为逐字符初始化,即每个字节都被初始化。同样的,在使用memset对整型数组进行初始化时,会把每个元素的每个字节初始化成ch

可能干说理论有点迷糊,所以下面结合一段代码解释。

#include <cstdio>
#include <cstring>
int main() {int a[5];memset(a, 1, sizeof(a));for (int i = 0; i < 5; i++) {printf("%d\n", a[i]);}return 0;
}

运行结果:

16843009
16843009
16843009
16843009
16843009

你会发现初始化的结果并不是1。
事实上,16843009写成二进制如下
16843009的二进制形式
对应我刚刚在前面说的,一个int类型为4字节,这里如果把这个数的4字节拆开看的话,每一位都是1。也就是说,它会把每一字节都填充上1。

memset(d, 1e5, sizeof(d));

这段代码的问题也就比较明显了,不过需要注意的是,由于为逐字节初始化,所以超过一个字节的内容会被自动截断,也就是说,1e5只会保留它的低8位,也就是10100000。
1e5的二进制表示
由于int类型储存位补码,最高位是符号位,当使用1e5对代码进行初始化的时候符号位被置为1,变成了负数。同理,这也就是为什么上面的代码在使用memset时,使用0x3f和0x3f3f3f3f等价的原因,但是。

使用memset初始化一定要慎重,对于整形数组,一般只用来初始化0、-1、0x3f这几个数字,其他的建议使用循环初始化,初始化其他值时尽量用for来初始化,或者使用fill函数和fill_n函数。

0x3f3f3f3f的原理

0x是16进制的标志,0x3f3f3f3f表示的十进制和二进制见下图。
0x3f3f3f3f的二进制
作为无穷大,一个数除了要保证足够大外,还要保证不能溢出。
使用上面这个值的主要原因是,两个0x3f3f3f3f的和只比int类型的最大值小一点,这样在两个无穷相加时能够保证不会溢出。
0x3f3f3f3f测试
同理,对于long long类型,可以使用0x3f3f3f3f3f3f3f3f来进行初始化
这个原理知道了之后就能解释为什么刚刚上面的第二段WA掉的代码问题在哪了:
取0x3f3f3f3f作为INF的话,只能保证两个INF相加不会溢出,但是三个INF就会溢出了,在下面这段代码的min中实际上三个数的和可能为负,导致结果错误。

ans = min(ans, a[i][k] + a[k][j] + b[i][j]);

这里可以加一个判断条件,或者适当降低INF的值,来避免这个问题。

总结

  1. 使用memset初始化一定要慎重,一般只用来初始化0、-1、0x3f这几个数字,其他的建议使用循环初始化,其他值尽量用for循环吧。
  2. 作为无穷大,一个数除了要保证足够大外,还要保证不能溢出。
    使用0x3f3f3f3f作为INF主要原因是,两个0x3f3f3f3f的和只比int类型的最大值小一点,这样既能保证一般情况下的足够大,在两个无穷相加时还能够保证不会溢出。

http://chatgpt.dhexx.cn/article/tWZ833PM.shtml

相关文章

双三次插值算法

配合阅读&#xff1a;https://blog.csdn.net/nandina179/article/details/85330552 今天学习了第三种图像缩放的方法&#xff0c;双三次插值法。由于理解能力比较差&#xff0c;看了好久的公式&#xff0c;还是云里雾里&#xff0c;但是为了督促自己学习&#xff0c;还是把已知…

图像的放大:双三次插值算法(C++实现)

双线性插值算法的不足就是细节处理的不好&#xff0c;换句话说&#xff0c;就是曲线拟合得不够光滑&#xff0c;所以又有了双三次插值算法。双三次插值算法是基于周围的16个像素点&#xff0c;通过计算16个像素点的权重&#xff0c;累积得到增加点的像素值的。 简单点理解&…

图像插值理论研究——双三次插值(双立方插值)

双三次插值&#xff0c;英文是Bicubic interpolation。双三次插值是一种更加复杂的插值方式&#xff0c;它能创造出比双线性插值更平滑的图像边缘。双三次插值方法通常运用在一部分图像处理软件、打印机驱动程序和数码相机中&#xff0c;对原图像或原图像的某些区域进行放大。A…

FPGA图像处理HLS实现三种图像缩放算法,线性插值、双线性插值、双三次插值,提供HLS工程和vivado工程源码

目录 一、三种图像缩放算法介绍线性插值双线性插值双三次插值 二、HLS实现线性插值图像缩放三、HLS实现双线性插值图像缩放四、HLS实现双三次插值图像缩放五、HLS在线仿真并导出IP六、其他FPGA型号HLS在线仿真并导出IP七、zynq7100开发板vivado工程八、上板调试验证九、福利&am…

数字图像处理100问—27 双三次插值( Bicubic Interpolation )

提示&#xff1a;内容整理自&#xff1a;https://github.com/gzr2017/ImageProcessing100Wen CV小白从0开始学数字图像处理 27 双三次插值&#xff08; Bicubic Interpolation &#xff09; 使用双三次插值将图像放大1.5倍 双三次插值是双线性插值的扩展&#xff0c;使用邻域…

用于数字成像的双三次插值技术​

点击上方“小白学视觉”&#xff0c;选择加"星标"或“置顶” 重磅干货&#xff0c;第一时间送达 双三次插值是使用三次或其他多项式技术的2D系统&#xff0c;通常用于锐化和放大数字图像。在图像放大、重新采样时&#xff0c;或是在软件中润饰和编辑图像时也会使到用…

插值算法(最邻近差值、双线性插值、双三次插值)

一、最邻近差值&#xff08;nearest&#xff09; 含义&#xff1a; 选取离目标点最近的点的值作为新的插入点的值。 两幅图坐标值变换关系&#xff1a; &#xff08;代码未验证&#xff09; for i1:size(dist,1)x round(i* (size(src,1)/size(dist,1))); %dst横坐标变换到s…

matlab双线性插值双三次插值对CUFED5进行处理

本文是摘抄与总结&#xff0c;仅供自己学习和日后查阅使用。 可以自己写一个双线性插值函数&#xff0c; ------------------------------------------------------------------- function outputimg my_imresize(A,n) % A 是图像矩阵,n是放缩的倍数 % 返回值outputimg是一…

双三次插值算法的C++实现与SSE指令优化

在上篇文章中&#xff0c;我们讲解了常见的最邻近插值算法、双线性插值算法和双三次插值算法的原理与实现&#xff0c;三种插值算法中双三次插值算法的插值效果最好&#xff0c;但其也是三种算法中计算复杂度最高、耗时最长的算法。本文在给出双三次插值C代码的基础上&#xff…

双三次插值 - 插值图像任意位置亚像素C++

双三次插值 - 插值图像任意位置亚像素C 一、概念 双三次插值又称立方卷积插值。三次卷积插值是一种更加复杂的插值方式。该算法利用待采样点周围16个点的灰度值作三次插值&#xff0c;不仅考虑到4 个直接相邻点的灰度影响&#xff0c;而且考虑到各邻点间灰度值变化率的影响。…

matlab 给图像双三次,图像灰度的双三次插值的MATLAB实现

相比C/C实现&#xff0c;图像灰度的双三次插值的MATLAB实现要方便的多&#xff0c;下面是MATLAB语言实现 clc,clear; ffimread(C:\Program Files\MATLAB\R2013a\bin\work\lena.bmp); [mm,nn]size(ff);%将图像隔行隔列抽取元素&#xff0c;得到缩小的图像f mmm/2;nnn/2; fzeros(…

java 双三次线性插值_三种常见的图像处理双三次插值算法

三种常见的图像处理双三次插值算法 双立方插值计算涉及16像素,间(i’, j’)像中的包括 小数部分的像素坐标。dx表示X方向的小数坐标。dy表示Y方向的小数坐标。 详细 能够看下图: 依据上述图示与双立方插值的数学表达式能够看出。双立方插值本质上图像16个像素点 权重卷积之和…

双三次插值 python实现_Python:用GPU实现双三次插值

它不是GPU(而是尝试利用线程和CPU的向量单元)&#xff0c;但是pyvips比scipy快很多&#xff0c;您可以测试一下。在 我做了个基准&#xff1a;import sys import time import scipy.ndimage import pyvips scale 10 n_loops 10 start time.time() test_image scipy.ndimage…

双三次插值及Matlab实现

双三次插值及Matlab实现 一、简单实例 采用简单实例进行对双三次插值的介绍&#xff0c;由于双三次插值对于目标图像的某一像素进行估计时&#xff0c;所采用的像素信息为其周围16个像素点信息&#xff0c;因此不同于最近邻插值和双线性插值&#xff0c;此时假设有 5 5 5\tim…

【opencv】最近邻插值、双线性插值、双三次插值(三次样条插值)

目录 1. 最近邻插值2. 双线性插值1&#xff09;简单理解2&#xff09;一般性 3. 双三次插值&#xff08;三次样条插值&#xff09;总结 b站 视频讲解 &#xff1a; https://www.bilibili.com/video/BV1wh411E7j9/ 1. 最近邻插值 举个简单例子&#xff1a;一个 3 3 3 \times 3…

挑战图像处理100问(27)——双三次插值

当我们需要对图像进行放大或缩小时&#xff0c;为了避免图像变形或失真&#xff0c;我们需要进行插值。插值是一种基于已知数据点&#xff0c;在这些数据点之间进行估计的方法。在图像处理中&#xff0c;常见的插值方法包括最邻近插值、双线性插值、双三次插值等。 双三次插值…

【图像超分辨(SR)】通俗直观彻底理解双线性插值、双三次插值及其作用

写在前面的一点话 网上讲解基本双线性插值、双三次线性插值的文章很多&#xff0c;但大部分都是只在讲为什么是这样&#xff0c;并不算非常通俗&#xff08;起码对我来说需要额外查很多资料来补充理解&#xff09;。很少有文章能够给初学者一些比较直观的理解&#xff0c;因此…

插值法(最邻近,双线性,双三次)的原理及实现

插值法(最邻近&#xff0c;双线性&#xff0c;双三次&#xff09;的原理及实现 常用的插值方法有最邻近插值法、双现象插值法和双三次插值法等&#xff0c;主要用于图像的放大或缩小。 缩小图像&#xff08;或称为下采样&#xff08;subsampled&#xff09; 或降采样&#xf…

表示关系x =y =z的c语言表达式为________.,为表示关系x≥y≥z,应使用C语言表达式____。...

为表焦距决定了画面的透视关系。 示关使用GREGRE ≥y≥桡神经沟位于 应C语言表关于脊柱正确的描写是() 建筑物或者其他设施以及建筑物上的搁置物、达式悬挂物发生( )造成他人损害的&#xff0c;所有人或者管理人应当承担民事责任,但能够证明自己没有过错的除外。 为表成对的脑颅…