将整数范围划分为几乎相等的整数范围
Divide an integer range into nearly equal integer ranges
我正在编写一个算法,它涉及到一组数字并将它们放入桶中。你能帮我实现这两个简单的方法吗?如果我需要解释更多,请告诉我。
// return a vector where each element represents the
// size of the range of numbers in the corresponding bucket
// buckets should be equal in size +/- 1
// doesn't matter where the bigger/smaller buckets are
vector<int> makeBuckets(int max, int numberOfBuckets);
// return which bucket n belongs in
int whichBucket(int max, int numberOfBuckets, int n);
示例输出
makeBuckets(10, 3) == { 3, 3, 4 }; // bucket ranges: (0, 2), (3, 5), (6, 9)
whichBucket(10, 3, 0) == 0;
whichBucket(10, 3, 1) == 0;
whichBucket(10, 3, 2) == 0;
whichBucket(10, 3, 3) == 1;
whichBucket(10, 3, 4) == 1;
whichBucket(10, 3, 5) == 1;
whichBucket(10, 3, 6) == 2;
whichBucket(10, 3, 7) == 2;
whichBucket(10, 3, 8) == 2;
whichBucket(10, 3, 9) == 2;
假设您需要将一个范围[0,n]分成k个桶。
- e = n/k(整数除!)将告诉您每个桶的最小大小。
- o = n % k将告诉您需要增加多少桶的大小。
- 现在循环k:
- 如果0> 0,创建一个大小为e+1的桶,减小0。
- 如果0 == 0,创建一个大小为e的桶。
如何最好地创建桶取决于n的大小。例如,如果你有一个小的n,你可以有一个大小为n的数组来存储每个数字的桶索引。在上面的循环中,您将填充该数组。那么查询哪个bucket()将在0(1)内运行。
然而,如果n很大,这是不切实际的。在这种情况下,您将完全隐式地执行bucket排序。这意味着,对于每个传入查询,您可以使用e和o直接计算相应的桶索引。感谢ypnos的回答。这是我在c++中的实现。
vector<int> makeBuckets(int max, int numberOfBuckets) {
int e = max / numberOfBuckets;
vector<int> b(numberOfBuckets, e);
fill(b.begin(), b.begin() + (max % numberOfBuckets), e + 1);
return b;
}
int whichBucket(int max, int numberOfBuckets, int n) {
return n * numberOfBuckets / max;
}
您可以使用朴素实现:
std::vector<std::size_t> parts(std::size_t m, std::size_t size)
{
std::vector<std::size_t> res(size);
for (std::size_t i = 0; i != m; ++i) {
++res[i % size];
}
return res;
}
std::size_t whichPart(std::size_t m, std::size_t size, std::size_t n)
{
std::size_t index = 0;
for (auto i : parts(m, size)) {
if (n < i) {
return index;
}
++index;
n -= i;
}
throw std::runtime_error("invalid argument");
}
给定一个整数范围[B, E),最均匀(大小差异不超过1)分割Nbin bin为:
[⌊分子B + E×N <子>子>÷N <子> bin子> 子> + 1)÷N <子>本子>)⌋<子>分子N <子>子> = 0到(N <子>本子> 1)子><一口>一口>。
示例-获取像素范围以满足多个线程:
for(unsigned int worker_index = 0; worker_index < n_workers; ++worker_index) {
std::cout
<< "[" << n_pixels * worker_index / n_workers << ", "
<< n_pixels * (worker_index + 1) / n_workers << ")"
<< std::endl;
}
[0,5)分成16个箱子
[0, 0)
[0, 0)
[0, 0)
[0, 1)
[1, 1)
[1, 1)
[1, 2)
[2, 2)
[2, 2)
[2, 3)
[3, 3)
[3, 3)
[3, 4)
[4, 4)
[4, 4)
[4, 5)
[0,18]到16个箱子
[0, 1)
[1, 2)
[2, 3)
[3, 4)
[4, 5)
[5, 6)
[6, 7)
[7, 9)
[9, 10)
[10, 11)
[11, 12)
[12, 13)
[13, 14)
[14, 15)
[15, 16)
[16, 18)
[0,36152320]分成16个箱子
[0, 2259520)
[2259520, 4519040)
[4519040, 6778560)
[6778560, 9038080)
[9038080, 11297600)
[11297600, 13557120)
[13557120, 15816640)
[15816640, 18076160)
[18076160, 20335680)
[20335680, 22595200)
[22595200, 24854720)
[24854720, 27114240)
[27114240, 29373760)
[29373760, 31633280)
[31633280, 33892800)
[33892800, 36152320)
相关文章:
- 将超出范围的整数分配给有符号字符类型
- 如何仅使用 While 循环在给定范围内找到可被 7 整除的计数整数
- 如果变量数据包含大于 vector 所有元素的整数,则仅在视觉工作室上接收"矢量下标超出范围"?
- 当我尝试将范围值存储为 8 位的固定宽度整数时,它向我显示一些其他值 [ASCII]
- 将整数范围映射到另一个范围
- C++标准强加的整数范围
- 如何编写一个 boost::spirit::qi 解析器来解析从 0 到 std::numeric_limits:<int>:max() 的整数范围?
- 特定整数范围内的数组值
- C++ 中的整数范围 - 当标准尚不存在时我该怎么办
- 生成编译时整数范围时类型不完整
- 浮点数或整数范围内的随机数
- 基于整数范围的模板专业化
- 可以返回基于字符串的整数范围的哈希函数
- 使用整数范围的算法
- 是否有一种简单/优雅的方法将整数范围压入STD向量?
- 将从0到x的整数范围分配给容器的最快方法
- 将整数范围划分为几乎相等的整数范围
- 将有符号整数范围映射为无符号
- 模板类中模板方法的基于整数范围的专用化
- 具有整数范围的Enum