拥有
我试图想出一个或两个方法来计算所提供的值属于哪个范围。
对于min=1,max = 10,范围为1,2、3,4、5,6、7,8、9-10。
另一个方法的行为如下所示:
这将用于为地图生成图例,其中标记的大小取决于值所属的范围。
我想知道是否有一个很好的算法解决方案。
我处理的数字是整数。
编辑:
另一个例子是:
对于min=1,max = 3,范围为ranges=2的数目
( a) 1-2、3-3
或
( b) 1-1、2-3
另一个方法的行为如下所示:
a)
或( b)
我不喜欢a)或b)。
发布于 2013-03-24 15:20:34
我会这样做:
首先,从数组开始,即范围数的大小,以跟踪每个范围的长度。让我们称其为bucket_sizes[number_of_ranges]
(max-min+1)/number_of_ranges
(整数除法)(max-min+1) % number_of_ranges
(整数除法的余数)。既然我们知道了每个桶的大小,就可以生成范围:
for (i=0, k=min; i<number_of_ranges; i++) {
ranges[i].lo = k;
ranges[i].hi = k+bucket_sizes[i]-1;
k += bucket_sizes[i];
}
要找到特定数字的范围,只需迭代ranges
数组并匹配ranges[i].lo <= number <= ranges[i].hi
所在的范围。
下面是我用来测试它的完整源代码(用C编写):
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct range
{
int lo;
int hi;
};
int generate_ranges(int min, int max, int number_of_ranges, struct range ranges[])
{
int i;
int bucket_sizes[number_of_ranges];
int even_length = (max-min+1)/number_of_ranges;
for(i=0; i<number_of_ranges; ++i)
bucket_sizes[i] = even_length;
/* distribute surplus as evenly as possible across buckets */
int surplus = (max-min+1)%number_of_ranges;
for(i=0; surplus>0; --surplus, i=(i+1)%number_of_ranges)
bucket_sizes[i] += 1;
int n=0, k=min;
for(i=0; i<number_of_ranges && k<=max; ++i, ++n){
ranges[i].lo=k;
ranges[i].hi=k+bucket_sizes[i]-1;
k += bucket_sizes[i];
}
return n;
}
int number_range_index(int number, int number_of_ranges, const struct range ranges[]) {
int i;
for(i=0; i<number_of_ranges; ++i)
if(number >= ranges[i].lo && number <= ranges[i].hi)
return i;
return number_of_ranges;
}
#define MAX_RANGES 50
int main(int argc, char *argv[]) {
int i;
struct range ranges[MAX_RANGES];
if(argc != 5) {
printf("usage: %s <min> <max> <number_of_ranges> <number>\n", argv[0]);
return EXIT_FAILURE;
}
int min = atoi(argv[1]);
int max = atoi(argv[2]);
int number_of_ranges = atoi(argv[3]);
int number = atoi(argv[4]);
assert(max > min);
assert(number >= min && number <= max);
assert(number_of_ranges > 0);
assert(number_of_ranges <= MAX_RANGES);
printf("min=%d max=%d number_of_ranges=%d number=%d\n\n", min, max, number_of_ranges, number);
int n = generate_ranges(min, max, number_of_ranges, ranges);
for(i=0; i<number_of_ranges; i++) {
if(i<n)
printf("%s[%d-%d]", i>0?",":"", ranges[i].lo, ranges[i].hi);
else
printf("%s[]", i>0?",":"");
}
printf("\n\n");
int number_idx = number_range_index(number, n, ranges);
printf("method(%d)->[%d,%d]\n", number, ranges[number_idx].lo, ranges[number_idx].hi);
return EXIT_SUCCESS;
}
发布于 2013-02-20 10:25:40
让n
是范围的数目。如果您可以将您的范围划分为相等的子范围,您可以这样做:
length_of_range = (max - min + 1) / n
For i = 1 to n:
start_of_range(i) = length_of_range * (i-1) + min
end_of_range(i) = start_of_range(i) + length_of_range - 1
method(number) = (number - min) / length_of_range + 1 // '/' is integer division
如果不能将它们划分为相等的子范围,那么第一个(max - min + 1) % n
子范围应该有长度((max - min + 1) / n) + 1
,其余的应该有长度(max - min + 1) / n
。知道了这一点,你应该能够自己调整上述公式。
发布于 2019-07-12 14:43:38
下面是奥斯卡·N的答案的C++11版本:
/** Divides a given range of values into consecutive sub-ranges as evenly as possible.
* Returns a vector of pairs. The first member of each pair is the min and the second, the max.
*/
std::vector< std::pair<int, int> > generateSubRanges( int mainRangeMin,
int mainRangeMax,
int numberOfSubRanges )
{
std::vector<std::pair<int, int> > result;
std::vector<int> bucket_sizes;
int i;
//init vectors
bucket_sizes.reserve( numberOfSubRanges );
result.reserve( numberOfSubRanges );
for( i = 0; i < numberOfSubRanges; ++i ){
bucket_sizes.push_back( 0 );
result.push_back( {0, 0} );
}
int even_length = (mainRangeMax-mainRangeMin+1)/numberOfSubRanges;
for(i=0; i<numberOfSubRanges; ++i)
bucket_sizes[i] = even_length;
/* distribute surplus as evenly as possible across buckets */
int surplus = (mainRangeMax-mainRangeMin+1)%numberOfSubRanges;
for(i=0; surplus>0; --surplus, i=(i+1)%numberOfSubRanges)
bucket_sizes[i] += 1;
int n=0, k=mainRangeMin;
for(i=0; i<numberOfSubRanges && k<=mainRangeMax; ++i, ++n){
result[i] = { k, k+bucket_sizes[i]-1 };
k += bucket_sizes[i];
}
return result;
}
https://softwareengineering.stackexchange.com/questions/187680
复制相似问题