如何在范围除法留余数后获得相等数量的元素
How to get equal number of elements after range division leaving a remainder
我知道标题不是最好的描述,但它是我能做的最好的。
长话短说,我正在尝试获取一系列数字,
让我们举个例子:
最小值:0 和最大值:10,
所以范围是 10 .
我想将范围划分为 n 个字段(用户给这个这个输入,所以它是可变的)然后创建 n threads-children ,使用 fork() ,每个人都会得到自己的 sub-range这些数字并使用这些数字执行一些代码,实际上它会检查这个数字是否是素数。
所以我的问题是我想不出一个公式来让数字平均分配。
我试过了:
for(int i = 0; i<n; i++){
//fork()
int temp = MIN + (i*(RANGE/n));
for(int a =; a< temp +(RANGE/n)+1; a++){
//check if prime
//other actions
}
}
但我知道这不会正常工作,因为如果我们有 3 个线程 (n),它将检查范围 (0,3) 、 (3,6) 、 (6,9) 因为
(RANGE/n) gives 3
这意味着在 children 的 N 个数字中 RANGE 的划分留下剩余的情况下,将永远不会检查最后一个数字,在此示例中为 10。
有什么聪明的方法来分割范围并每次检查不同数量的进程的所有数字吗?
提前致谢
如果您的任务是验证一个数是否为质数,则将较大的数放在较小的组中会很方便(因为验证它们是否为质数会更加困难)。
您可以使用由 MAX 启动的策略。然后创建以下间隔:例如{MAX-1,MAX-2}(依此类推)直到您拥有所需范围的数量。
How to get equal number of elements after range division leaving a remainder
各种方法。
一个关键问题是0
和10
是否都包含在整数范围内:是[0... 10]
还是[0... 10)
还是...?注意到 ]
或 )
了吗?让我们假设包含列表端点并且 [0... 10]
是 11 个不同的整数值。
注意:也有极端情况,比如11个号码分成12组。
下面从范围的第一个 1/n
部分构成子范围,然后是剩余范围的 1/(n-1)
部分,依此类推
void range(int n, int inclusive_min, int inclusive_max) {
printf("Range [%d %d] / %d\n", inclusive_min, inclusive_max, n);
for(int i = n; i > 0 && inclusive_min <= inclusive_max; i--) {
int range = 1 + inclusive_max - inclusive_min;
int sub_range = range/i;
if (sub_range == 0) sub_range = 1;
printf("Sub range [%d %d]\n", inclusive_min, inclusive_min + sub_range - 1);
inclusive_min += sub_range;
}
}
int main(void) {
range(3, 0, 10);
range(2, 0, 10);
range(5, 0, 10);
range(3, 0, 1);
return 0;
}
输出
Range [0 10] / 3
Sub range [0 2]
Sub range [3 6]
Sub range [7 10]
Range [0 10] / 2
Sub range [0 4]
Sub range [5 10]
Range [0 10] / 5
Sub range [0 1]
Sub range [2 3]
Sub range [4 5]
Sub range [6 7]
Sub range [8 10]
Range [0 1] / 3
Sub range [0 0]
Sub range [1 1]
一个更优雅的解决方案,类似于 Bresenham's line algorithm
void range(int n, int inclusive_min, int inclusive_max) {
printf("Range [%d %d] / %d\n", inclusive_min, inclusive_max, n);
int range = 1 + inclusive_max - inclusive_min;
int sub_range = range / n;
int sub_range_res = range % n;
int p = 0;
for (int i = 0; i < n; i++) {
int next = inclusive_min + sub_range;
p += sub_range_res;
if (2 * p >= n) { // like p >= n/2 without integer truncation.
p -= n;
next++;
}
if (next > inclusive_min) {
printf("Sub range %d:[%d %d]\n", i, inclusive_min, next - 1);
}
inclusive_min = next;
}
}
输出
Range [0 10] / 3
Sub range 0:[0 3]
Sub range 1:[4 6]
Sub range 2:[7 10]
Range [0 10] / 2
Sub range 0:[0 5]
Sub range 1:[6 10]
Range [0 10] / 5
Sub range 0:[0 1]
Sub range 1:[2 3]
Sub range 2:[4 6]
Sub range 3:[7 8]
Sub range 4:[9 10]
Range [0 1] / 3
Sub range 0:[0 0]
Sub range 2:[1 1]
我知道标题不是最好的描述,但它是我能做的最好的。
长话短说,我正在尝试获取一系列数字,
让我们举个例子:
最小值:0 和最大值:10,
所以范围是 10 .
我想将范围划分为 n 个字段(用户给这个这个输入,所以它是可变的)然后创建 n threads-children ,使用 fork() ,每个人都会得到自己的 sub-range这些数字并使用这些数字执行一些代码,实际上它会检查这个数字是否是素数。
所以我的问题是我想不出一个公式来让数字平均分配。
我试过了:
for(int i = 0; i<n; i++){
//fork()
int temp = MIN + (i*(RANGE/n));
for(int a =; a< temp +(RANGE/n)+1; a++){
//check if prime
//other actions
}
}
但我知道这不会正常工作,因为如果我们有 3 个线程 (n),它将检查范围 (0,3) 、 (3,6) 、 (6,9) 因为
(RANGE/n) gives 3
这意味着在 children 的 N 个数字中 RANGE 的划分留下剩余的情况下,将永远不会检查最后一个数字,在此示例中为 10。
有什么聪明的方法来分割范围并每次检查不同数量的进程的所有数字吗?
提前致谢
如果您的任务是验证一个数是否为质数,则将较大的数放在较小的组中会很方便(因为验证它们是否为质数会更加困难)。
您可以使用由 MAX 启动的策略。然后创建以下间隔:例如{MAX-1,MAX-2}(依此类推)直到您拥有所需范围的数量。
How to get equal number of elements after range division leaving a remainder
各种方法。
一个关键问题是0
和10
是否都包含在整数范围内:是[0... 10]
还是[0... 10)
还是...?注意到 ]
或 )
了吗?让我们假设包含列表端点并且 [0... 10]
是 11 个不同的整数值。
注意:也有极端情况,比如11个号码分成12组。
下面从范围的第一个 1/n
部分构成子范围,然后是剩余范围的 1/(n-1)
部分,依此类推
void range(int n, int inclusive_min, int inclusive_max) {
printf("Range [%d %d] / %d\n", inclusive_min, inclusive_max, n);
for(int i = n; i > 0 && inclusive_min <= inclusive_max; i--) {
int range = 1 + inclusive_max - inclusive_min;
int sub_range = range/i;
if (sub_range == 0) sub_range = 1;
printf("Sub range [%d %d]\n", inclusive_min, inclusive_min + sub_range - 1);
inclusive_min += sub_range;
}
}
int main(void) {
range(3, 0, 10);
range(2, 0, 10);
range(5, 0, 10);
range(3, 0, 1);
return 0;
}
输出
Range [0 10] / 3
Sub range [0 2]
Sub range [3 6]
Sub range [7 10]
Range [0 10] / 2
Sub range [0 4]
Sub range [5 10]
Range [0 10] / 5
Sub range [0 1]
Sub range [2 3]
Sub range [4 5]
Sub range [6 7]
Sub range [8 10]
Range [0 1] / 3
Sub range [0 0]
Sub range [1 1]
一个更优雅的解决方案,类似于 Bresenham's line algorithm
void range(int n, int inclusive_min, int inclusive_max) {
printf("Range [%d %d] / %d\n", inclusive_min, inclusive_max, n);
int range = 1 + inclusive_max - inclusive_min;
int sub_range = range / n;
int sub_range_res = range % n;
int p = 0;
for (int i = 0; i < n; i++) {
int next = inclusive_min + sub_range;
p += sub_range_res;
if (2 * p >= n) { // like p >= n/2 without integer truncation.
p -= n;
next++;
}
if (next > inclusive_min) {
printf("Sub range %d:[%d %d]\n", i, inclusive_min, next - 1);
}
inclusive_min = next;
}
}
输出
Range [0 10] / 3
Sub range 0:[0 3]
Sub range 1:[4 6]
Sub range 2:[7 10]
Range [0 10] / 2
Sub range 0:[0 5]
Sub range 1:[6 10]
Range [0 10] / 5
Sub range 0:[0 1]
Sub range 1:[2 3]
Sub range 2:[4 6]
Sub range 3:[7 8]
Sub range 4:[9 10]
Range [0 1] / 3
Sub range 0:[0 0]
Sub range 2:[1 1]