有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java将一个数字分成更小的随机整数

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

比如,如果我输入数字12和它应该划分的部分的数量,我希望它返回类似于(4个部分)8,2,1,1的东西。但不能加倍,因为我需要int值。
我早些时候找到了一个答案,但它只适用于双打。不是ints
(这就是我找到的那个)

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;

我尝试通过以下操作将此代码更改为使用Ints工作:

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;
}

但当使用number:512运行该命令并使用10个部分(getDivider()将返回10)时,itll将输出以下内容:

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

还有很多这样的数字

谢谢


共 (4) 个答案

  1. # 1 楼答案

    这里有一个算法可以完成这项工作:

    1. 创建一个长度为parts+1的数组
    2. 将值0和number添加到数组中,然后填充 它使用random.nextInt(number-1) + 1使用唯一的随机值 获取0和number之间的值,不包括范围限制
    3. 对数组进行排序
    4. 从索引1开始遍历排序数组。连续的 差array[i] - array[i-1]将是一组 总和为number

    如果允许零,那么在填充数组时就不需要唯一性标准。 如果您需要唯一性,您可以考虑将随机值添加到^ {< CD7> }(它仅是{{CD8}}的唯一条目),直到大小符合您的要求,然后将其转换为^ {CD9}}。

    下面是一个实际的实现:

    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]等结果

  2. # 2 楼答案

    假设每个术语至少为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。...左右玩得开心

    这是家庭作业吗

  3. # 3 楼答案

    一种低效但非常简单的方法是循环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]
    

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

  4. # 4 楼答案

    使用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;
    }