我已经为有序的整数数组实现了这个搜索算法。它适用于我提供的第一个数据集(500个整数),但在较长的搜索时失败。但是,所有这些集合都与我为分配实现的其他四种搜索算法完美配合。
这是在第178行返回seg故障的函数(由于意外的负m值)。任何帮助将不胜感激。
CODE:
155 /* perform Algortihm 'InterPolationSearch' on the set
156 * and if 'key' is found in the set return it's index
157 * otherwise return -1 */
158 int
159 interpolation_search(int *set, int len, int key)
160 {
161 int l = 0;
162 int r = len - 1;
163 int m;
164
165 while (set[l] < key && set[r] >= key)
166 {
167
168 printf ("m = l + ((key - set[l]) * (r - l)) / (set[r] - set[l])\n");
169
170 printf ("m = %d + ((%d - %d) * (%d - %d)) / (%d - %d);\n", l, key, set[l], r, l, set[r], set[l]);
171 m = l + ((key - set[l]) * (r - l)) / (set[r] - set[l]);
172 printf ("m = %d\n", m);
173
174 #ifdef COUNT_COMPARES
175 g_compares++;
176 #endif
177
178 if (set[m] < key)
179 l = m + 1;
180 else if (set[m] > key)
181 r = m - 1;
182 else
183 return m;
184 }
185
186 if (set[l] == key)
187 return l;
188 else
189 return -1;
190 }
输出:
m = l + ((key - set[l]) * (r - l)) / (set[r] - set[l])
m = 0 + ((68816 - 0) * (100000 - 0)) / (114836 - 0);
m = -14876
三江源!
里斯
答案 0 :(得分:5)
68816 * 100000超过2 ^ 31,这很可能是您机器的int
数据类型的限制。你遇到了整数溢出。
如果您的编译器支持它,请尝试更改为long long
。您可以通过运行
#include <stdlib.h>
printf("the long long type is %u bits", (unsigned int) (CHAR_BIT * sizeof (long long)));
正如Naveen指出的那样,您还需要确保以这种精度进行实际计算。这可以通过施放来完成。
答案 1 :(得分:1)
您的算术可能超出了平台上int
的大小。
你需要做两件事之一。使用更宽的整数类型(如果可用),或重新计算您的计算,这样您就不需要创建如此大的中间值。
答案 2 :(得分:1)
m = 0 + ((68816 - 0) * (100000 - 0)) / (114836 - 0);
68816 * 100000 = 6881600000 = (binary)110011010001011001110001000000000
那是33位。几乎所有平台int
都是32位或(在极少数情况下)16位。
您可以尝试使用保证至少为64位的long long
(在C99中添加,但大多数编译器也支持在C90中)。
答案 3 :(得分:0)
您需要注意整数溢出。最好将m
计算为大于int
的类型,然后在完成后转回int
。
此外,如果您的集合包含重复项,则可能需要小心,因为在同一行(即set[r] == set[l]
时)可能会出现零错误除法。
答案 4 :(得分:0)
这是因为计算(68816 - 0) * (100000 - 0)
的中间值超过了int
内可以保留的值。您可以将中间值转换为可以容纳更大数字的数据类型(例如long long
)来解决问题
答案 5 :(得分:0)
为避免数据溢出等问题,您还可以使用大数字库。一个很好的例子是:http://gmplib.org/。当然它会增加一点开销,但总体性能非常好。