给定范围如0..5 ..... 20 .... 25..40 ... 50 ...... 100,我必须确定一个数字在哪个范围内。所以问题是确定数字范围的最快方法,例如aNum = 56在50 ...... 100范围内。确定范围后,我将范围的起始数分配给aNum,在这种情况下为50。所以最后,aNum = 50。
我只是想知道它是否会花费恒定的时间O(1)。
任何建议都将不胜感激。您可以使用的任何数据结构。
答案 0 :(得分:4)
对于显示的范围类型(可被5整除),以下算法是好的:
将所有范围分段5(因此,例如25-40实际上是3个范围:25-29,30-34和35-39。
创建一个将段指定为范围的查找数组。因此,例如,如果范围25-39是#4,而段25-29是#15,30-34是#16,35-39是#17。然后查找[15] = 4,查找[16] = 4,查找[17] = 4,等等。
现在这是一个分裂的问题。将数字除以5得到D,然后是#= lookup [D]。
如果您的范围不规则且无法通过公共数字整除,则可以以内存为代价创建包含所有可能值的查找表。
这是线性时间算法。
答案 1 :(得分:2)
假设有N
个有序范围,可以使用二进制搜索算法在O(Log N)
中找到目标范围。不到那个是不可能的。例如,您可以考虑所有范围相等的情况,例如:
1..2..3..4.. .. 99..100
在这种情况下,找到目标范围等同于在O(1)
中无法在排序数组中查找数字。
答案 2 :(得分:0)
以下是一个示例算法:
以下代码说明了在C中实现此算法的示例:
#include <stdio.h>
#include <stdlib.h>
/*We assume there is a fixed number of ranges*/
#define RANGE_COUNT 4
int main(int argc, char** argv){
/*Set the minimum and maximum values for each range*/
int ranges[RANGE_COUNT][2] = {{0, 5}, {20, 20}, {25, 40}, {50, 100}};
int x = 0, num = 0;
/*In this example, we are using the command-line for input*/
if(argc != 2){
fprintf(stderr, "Usage: %s <number>", argv[0]);
exit(1);
}
/*We need to ensure that the input is a number*/
if(!(num = atoi(argv[1])) && argv[1][0] != '0'){
fprintf(stderr, "Error: \"%s\" is not a number", argv[1]);
exit(1);
}
/*See if the number is in any of the ranges*/
for(x = 0; x < RANGE_COUNT; x++){
if(num >= ranges[x][0] && num <= ranges[x][1]){
/*If the number is in a range, say which one it is*/
printf("The number %d is in the range %d..%d\n",
num, ranges[x][0], ranges[x][1]);
/*Set the number equal to the minimum value of the range it is in*/
num = ranges[x][0];
printf("num = %d\n", num);
exit(0);
}
}
/*If the number is not in any of these ranges, indicate that it is not*/
printf("The number %d is not in any of these ranges\n", num);
return 0;
}