范围除法后如何获得相等数量的元素

时间:2019-03-24 02:23:08

标签: c multithreading formula division

我知道标题不是最好的描述,但它是我能做的最好的描述。
长话大说,我正在尝试获取一系列数字, 让我们举个例子:

MIN:0和MAX:10, 因此范围将是10。

我想将范围划分为n个字段(用户提供此输入,因此它是可变的),然后使用fork()创建n个thread-children,其中每个对象将获得这些数字的自己的子范围并执行一些使用这些数字的代码,实际上它将检查该数字是否为质数。
所以我的问题是我想不出要写的公式,以便将数字平均分配。

我尝试过:

    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)给出3

这意味着在RANGE与N个孩子的除数留下的情况下,将永远不会检查最后一个数字(在此示例中为10)。
是否有任何明智的方法来分割范围并每次按不同的进程数检查所有数字?
预先感谢

2 个答案:

答案 0 :(得分:0)

如果您的任务是验证数字是否为质数,则将较大的数字分成较小的组是很方便的(因为更难验证它们是否为质数)。

您可以使用MAX发起的策略。然后创建以下间隔:例如{MAX-1,MAX-2}(依此类推),直到获得所需范围的数量为止。

答案 1 :(得分:0)

  

范围划分后如何获得相等数量的元素

各种方法。

一个关键问题是010是否都包含在整数范围内:是[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]