将数字除以较小的随机整数

时间:2014-05-12 16:02:06

标签: java random divide

所以我需要的是基本上在主题中描述。

如果我将数字12和它应该分配的部分数量放入,我希望它返回类似(4个部分)8,2,1,1的东西。但不是双倍因为我需要值为INT。
我之前找到了一个答案,但它只使用了双打。没有注意。
(这是我发现的那个)

public double[] divideUniformlyRandomly(double number, int part) {
    double uniformRandoms[] = new double[part];
    Random random = new Random();
    double mean = number / part;
    double sum = 0.0;
    for (int i=0; i<part / 2; i++) {
        uniformRandoms[i] = random.nextDouble() * mean;
        uniformRandoms[part - i - 1] = mean + random.nextDouble() * mean;
        sum += uniformRandoms[i] + uniformRandoms[part - i -1];
    }
    uniformRandoms[(int)Math.ceil(part/2)] = uniformRandoms[(int)Math.ceil(part/2)] + number - sum;
    return uniformRandoms;

我曾尝试使用Int更改此代码以使其工作:

public int[] divide(int number) {
    int part = getDivider(number);
    int uniformRandoms[] = new int[part];
    Random random = new Random();
    int mean = number / part;
    int sum = 0;
    for (int i=0; i<part / 2; i++) {
        uniformRandoms[i] = random.nextInt() * mean;
        uniformRandoms[part - i - 1] = mean + random.nextInt() * mean;
        sum += uniformRandoms[i] + uniformRandoms[part - i -1];
    }
    uniformRandoms[(int)Math.round(part/2)] = uniformRandoms[(int)Math.round(part/2)] + number - sum;
    for(int i : uniformRandoms)
        System.out.println(i);
    return uniformRandoms;
}

但是当使用数字运行时:512并使用10个部分(getDivider()将返回10)itll输出:

-1058809647, -2102647561, 469849949, 1627965716, -290084223, -33347991

还有更多这类数字。

感谢。

4 个答案:

答案 0 :(得分:1)

假设每个术语至少应为1。

public int[] divide(int number, int parts) {
    int[] randoms = new int[parts];
    Arrays.fill(randoms, 1); // At least one
    int remainder = number - parts;
    Random random = new Random();
    for (int i = 0; i < parts - 1 && remainder > 0; ++i) {
        int diff = random.nextInt(remainder);
        randoms[i] += diff;
        remainder -= diff;
   }
   randoms[parts - 1] += remainder;
   Arrays.sort(randowms);

   // Reverse (for getting a descending array):
   for (int i = 0, j = parts - 1; i < j; ++i, --j) {h
       int temp = randoms[i];
       randoms[i] = randoms[j];
       randoms[j] = temp;
   }
   return randoms;
}

这是均匀分布。为此,可以迭代直到余数变为0,每次随机选择一个索引来增加。或者。玩得开心。

这是家庭作业吗?

答案 1 :(得分:0)

使用Random#nextInt(int)

public int[] divideUniformlyRandomly(int number, int parts) {
    Random random = new Random();
    int[] randoms = new int[];
    for(int i = 0; i < parts; i++) {
        randoms[randoms.length] = random.nextInt(number);
    }
    return randoms;
}

答案 2 :(得分:0)

这是一个可以完成工作的算法:

  1. 创建一个长度为parts+1的数组。
  2. 将值0和number添加到数组中,然后填充剩余部分 使用random.nextInt(number-1) + 1使用唯一随机值 获取0到number之间的值,不包括范围限制。
  3. 对数组进行排序。
  4. 遍历从索引1开始的排序数组。连续 差异array[i] - array[i-1]将是一组正整数 总和为number
  5. 如果允许使用零,则填充数组时不需要唯一性标准。 如果您需要唯一性,可以考虑将随机值添加到HashSet(仅.add()的唯一条目),直到大小符合您的要求,然后将其转换为.toArray()

    这是一个实际的实现:

    import java.util.Arrays;
    import java.util.HashSet;
    import java.util.Random;
    
    public class SumToTotal {
       public static Random r = new Random();
    
       public static int[] divide(int number, int number_of_parts) {
          HashSet<Integer> uniqueInts = new HashSet<Integer>();
          uniqueInts.add(0);
          uniqueInts.add(number);
          int array_size = number_of_parts + 1;
          while (uniqueInts.size() < array_size) {
             uniqueInts.add(1 + r.nextInt(number - 1));
          }
          Integer[] dividers = uniqueInts.toArray(new Integer[array_size]);
          Arrays.sort(dividers);
          int[] results = new int[number_of_parts];
          for(int i = 1, j = 0; i < dividers.length; ++i, ++j) {
             results[j] = dividers[i] - dividers[j];
          }
          return results;
       }
    
       public static void main(String[] args) {
          System.out.println(Arrays.toString(divide(12, 5)));
       }
    }
    

    这会产生[3, 2, 1, 2, 4][1, 5, 2, 3, 1]等结果。

答案 3 :(得分:0)

一种低效但非常简单的方法是循环n次并将其中一个索引递增一个。

    void divider(int number, int divisions)
    {
        Random rand = new Random();
        int[] container = new int[divisions];

        System.out.print(number + "->");
        while (number > 0)
        {
            container[rand.nextInt(divisions)]++;
            number--;
        }
        for (int i : container)
        {
            System.out.print("[" + i + "]");
        }
    }

divider(1000, 20)可以输出:

1000->[57][43][60][35][39][47][45][59][51][71][52][54][58][48][33][49][49][46][49][55]
1000->[60][50][49][53][42][52][52][45][40][51][52][51][53][47][51][46][53][56][45][52]
1000->[52][43][49][53][57][45][42][43][61][61][58][44][46][49][52][39][63][45][54][44]

在去旧电脑的路上,只需要11毫秒就可以将100.000分成20个不同的“容器”。因此,如果您不经常使用这个和/或非常大的数字,这是完全有效的方法。