在程序设计特别是有向图算法中经常需要去表达不可达的距离,也就是无穷大来填充邻接矩阵,初学者包括我自己会使用类似9999999(一刀暴击?)或者干脆直接Integer.MAX_VALUE这样不专业的手法,前者只需要根据数据的范围合理划定即可(尽管看起来非常难受),而后者——如果算法中从存在松弛操作
例如
dist[k] = Math.min(dist[k], dist[t] + graph[t][k]);
//源自于Dijkstra的更新部分
dist[k] 便会超过Integer的最大范围从而变为负数,答案出错。
在很多算法高手的代码中经常见到0x3F3F3F3F这样一个数(下文记作INF)来代替正无穷,仔细研究,十分巧妙。
请看分析:
首先我们来看INF的各个进制表示:
①由二进制前两位为0,可知如果将INF左移1操作也就是INF * 2,是小于Integer的范围的,也就是说可以表达 无穷大 + 无穷大 依然等于 无穷大。
②INF在数量级上为109+k,已经可以满足绝大多数程序设计的数据上限。
③这一点基于C++程序设计,在C与C++中,memset函数的原理是按字节赋值,于是就可以很方便的赋予无穷大如下
memset(array, 0x3f, sizeof(array));
而对于Java程序设计,这一点似乎不明显,Array.fill方法仍然是按照给定的参数直接赋值,所以Java中必须这样写
Arrays.fill(dist, 0x3f3f3f3f);
基于以上分析,0x3F3F3F3F是一个表示无穷大很好的选择。