所以我需要的是基本上在主题中描述。
如果我将数字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
还有更多这类数字。
感谢。
答案 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)
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)
这是一个可以完成工作的算法:
parts+1
的数组。number
添加到数组中,然后填充剩余部分
使用random.nextInt(number-1) + 1
使用唯一随机值
获取0到number
之间的值,不包括范围限制。array[i] - array[i-1]
将是一组正整数
总和为number
。如果允许使用零,则填充数组时不需要唯一性标准。
如果您需要唯一性,可以考虑将随机值添加到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个不同的“容器”。因此,如果您不经常使用这个和/或非常大的数字,这是完全有效的方法。