public static void main(String[] args){ Random r = new Random();//r用来产生一个0-100的随机数。 List<Integer> list = new ArrayList<Integer>();//因为不知道要被分成几分,用List更好些。 boolean flag = true; int sum = 100; while(flag){ int n = r.nextInt(101); if(n==0){ continue; }else if((sum-n)>0){ list.add(n); sum = sum-n; }else if((sum-n)==0){ list.add(n); flag = false; }else if((sum-n)<0){ continue; } } for(Integer a:list){ System.out.println(a); } }
我的实现如下,基本和楼上实现类似: private int[] getRandomArray(int size) { int[] percent = null; if (size > 0) { percent = new int[size]; if (1 == size) { percent[0] = 100; } else { int i = 0; int num = 100; while (true) { percent[i] = RandomUtils.nextInt(101); num -= percent[i]; if (num == 0) { break; } else { if ((num < 0) || (i == size - 1)) { percent[i] += num; break; } } i++; } } } return percent; }
import java.util.Stack; public class Test { private static Stack<Integer> array = new Stack<Integer>(); public static void main(String[] args) { caifen(100, 0); } public static void caifen(int n, int yushu) { if (n == 0) { System.out.println(array); return; } for (int i = yushu + 1; i <= n; i++) { array.push(i); caifen(n - i, i); array.pop(); } } }
import java.util.*; class Chaifen { int n; public Chaifen(int n) { this.n = n; } public int[] chaifen() { int[] a = new int[n]; Random rand = new Random(); int shengyu = 100; for (int i=0;i<n-1;i++) { a[i] = rand.nextInt(shengyu); shengyu = shengyu - a[i]; } a[n-1] = shengyu; return a; } public static void main(String[] args) { Chaifen ch = new Chaifen(5); int[] b = ch.chaifen(); for (int i=0;i<b.length;i++) { System.out.println(b[i]); } } }
这个 刚写的 public static int[] go() { Random r = new Random(); List<Integer> list = new ArrayList<Integer>(); int sum = 0; while (true) { int t = 0; while (t == 0) { t = r.nextInt(100); } sum += t; if (sum < 100) { list.add(t); } if (sum == 100) { list.add(t); int[] a = new int[list.size()]; for (int i = 0; i < a.length; i++) { a[i] = list.get(i); } return a; } if (sum > 100) { sum -= t; } } } public static void main(String[] args) { System.out.println(Arrays.toString(go())); }
private static int[] getRandomArray(int size) { int[] percent = new int[size]; int s = 100; double k = 0.6;//波动常数,位于0~1之间。如果=0,平均分配;=1,最大波动 for (int i = 0; i < size - 1; i++) { double x = s / (size - i); double y = Math.random() - 0.5; double z = x + (y > 0 ? s - x : x) * y * k; percent[i] = (int) z; s -= percent[i]; } percent[size - 1] = s; return percent; }
不用那么麻烦,可以这样做:public int[] f(int total, int n) { if (total < 0 || n <= 0) { throw new IllegalArgumentException(); } int[] x = new int[n]; Random r = new Random(); for (int i = 0; i < n - 1; i++) { x[i] = r.nextInt(total + 1); total -= x[i]; } x[n - 1] = total; return x; }另:6 楼的方法是不行的,因为这样生成的几个数总有 n - 1 个是小于等于 total / n 的,但这不是所有的情况,比如 [ 1, 33, 33, 33 ] 就不能用 6 楼的方法生成出来。
上面的很多算法都是不行的。因为当拆分的份数越来越多的时候,最后生成的数组的 第一位=1 和 最后一位=1 的概率相差就越来越大。除非在生成的数组后面做一个乱序的处理。同时,还有一些问题。拿9L的来说,int n = r.nextInt(101); 当sum=10的时候,因为随机的还是0~100的整数,那这时候,随机生成的数中10~100之间的数,因为都>=10,所以最后的结果只能是10。而这时候,结果=10和 结果=小于10的某一个数的概率就完全不等了。所以这样的算法完全不行。如果要改的话,应该是 int n = r.nextInt(sum)+1;我的想法是。随机生成一个区间的数,然后把这个数随机的加到数组中的某一个数上面。 private static int[] getRandomArray(int size) { int[] percent = new int[size]; Arrays.fill(percent, 1);//保证最小的数==1 int s = 100 - size; int k = 5;//常数,==1比较平均的分配,越大越不平均。 Random r = new Random(); while (s > 0) { int x = r.nextInt(size); int y = r.nextInt(k > s ? s : k) + 1; percent[x] += y; s -= y; } return percent; }
那就这样 public static void go() { Random r = new Random(); List<Integer> list = new ArrayList<Integer>(); int sum = 0; while (true) { int t = 0; while (t == 0) { t = r.nextInt(100); } sum += t; if (sum == 100) { list.add(t); System.out.println(list); return; } if (sum < 100) { list.add(t); } if (sum > 100) { sum = 0; list.clear(); } } } public static void main(String[] args) { for (int i = 0; i < 10; i++) go(); }
public static void compute(int[] data, int sum) {
boolean[] state = new boolean[data.length];
int p = 0;
int temp = 0; while (true) {
while (p != data.length) {
if (!state[p]) {
state[p] = true;
temp += data[p];
if (temp == sum) {
for (int i = 0; i < data.length; i++) {
if (state[i]) {
System.out.print(data[i] + " ");
}
}
return;
}
if (temp > sum) {
state[p] = false;
temp -= data[p];
}
}
p++;
} while (state[p - 1]) {
state[p - 1] = false;
temp -= data[p - 1];
p--;
if (p == 0) {
return;
}
} while (!state[p - 1]) {
p--;
if (p == 0) {
return;
}
} state[p - 1] = false;
temp -= data[p - 1];
}
} public static void go() {
Random r = new Random();
int[] data = new int[100];
for (int i = 0; i < data.length; i++) {
int t = 0;
while (t == 0) {
t = r.nextInt(100);
}
data[i] = t;
}
compute(data, 100);
} public static void main(String[] args) {
go();
}
{
public static int[] divideBy(int num){
double[] possiblity=new double[num];
possiblity[0]=1;
for(int i=0;i<num-1;i++){
divideIndex(possiblity,i);
}
int[] result=new int[num];
int sum=0;
for(int i=0;i<num-1;i++){
result[i]=(int)(possiblity[i]*100);
sum+=result[i];
}
result[num-1]=100-sum;
return result;
} //随机的拆分某个已生成的概率 e.g 0.53=0.36+0.17
public static void divideIndex(double[] array,int endIndex){
//随机选择一个已生成的概率进行拆分,分成两个概率
double random=Math.random();//0-1.0之间的一个值,用于随机生成下标
int index=((int)(random/(1.0/(endIndex+1))));
//将拆分后的俩个概率填入
double tmp=array[index];
array[index]=tmp*Math.random();
array[endIndex+1]=tmp-array[index];
}
public static void main(String[] args)
{
int[] tmp=divideBy(3);
for(int i:tmp)
System.out.println(i+"");
}
}
100 分 5份
100 生成0-100的随机数 89
100-89
0-11的随机数 5
11-5
0-6的随机数
统统放到int数组就可以了
Random r = new Random();//r用来产生一个0-100的随机数。
List<Integer> list = new ArrayList<Integer>();//因为不知道要被分成几分,用List更好些。
boolean flag = true;
int sum = 100;
while(flag){
int n = r.nextInt(101);
if(n==0){
continue;
}else if((sum-n)>0){
list.add(n);
sum = sum-n;
}else if((sum-n)==0){
list.add(n);
flag = false;
}else if((sum-n)<0){
continue;
}
}
for(Integer a:list){
System.out.println(a);
}
}
private int[] getRandomArray(int size) {
int[] percent = null;
if (size > 0) {
percent = new int[size];
if (1 == size) {
percent[0] = 100; } else {
int i = 0;
int num = 100;
while (true) {
percent[i] = RandomUtils.nextInt(101);
num -= percent[i];
if (num == 0) {
break;
} else {
if ((num < 0) || (i == size - 1)) {
percent[i] += num;
break;
}
}
i++;
}
}
}
return percent;
}
import java.util.Stack;
public class Test {
private static Stack<Integer> array = new Stack<Integer>();
public static void main(String[] args) {
caifen(100, 0);
}
public static void caifen(int n, int yushu) {
if (n == 0) {
System.out.println(array);
return;
}
for (int i = yushu + 1; i <= n; i++) {
array.push(i);
caifen(n - i, i);
array.pop();
}
}
}
class Chaifen
{
int n;
public Chaifen(int n)
{
this.n = n;
}
public int[] chaifen()
{
int[] a = new int[n];
Random rand = new Random();
int shengyu = 100;
for (int i=0;i<n-1;i++)
{
a[i] = rand.nextInt(shengyu);
shengyu = shengyu - a[i];
}
a[n-1] = shengyu;
return a;
}
public static void main(String[] args)
{
Chaifen ch = new Chaifen(5);
int[] b = ch.chaifen();
for (int i=0;i<b.length;i++)
{
System.out.println(b[i]);
}
}
}
Random r = new Random();
List<Integer> list = new ArrayList<Integer>();
int sum = 0;
while (true) {
int t = 0;
while (t == 0) {
t = r.nextInt(100);
}
sum += t;
if (sum < 100) {
list.add(t);
}
if (sum == 100) {
list.add(t);
int[] a = new int[list.size()];
for (int i = 0; i < a.length; i++) {
a[i] = list.get(i);
}
return a;
}
if (sum > 100) {
sum -= t;
}
}
} public static void main(String[] args) {
System.out.println(Arrays.toString(go()));
}
private static int[] getRandomArray(int size) {
int[] percent = new int[size];
int s = 100;
double k = 0.6;//波动常数,位于0~1之间。如果=0,平均分配;=1,最大波动
for (int i = 0; i < size - 1; i++) {
double x = s / (size - i);
double y = Math.random() - 0.5;
double z = x + (y > 0 ? s - x : x) * y * k;
percent[i] = (int) z;
s -= percent[i];
}
percent[size - 1] = s;
return percent;
}
throw new IllegalArgumentException();
} int[] x = new int[n];
Random r = new Random(); for (int i = 0; i < n - 1; i++) {
x[i] = r.nextInt(total + 1);
total -= x[i];
}
x[n - 1] = total; return x;
}另:6 楼的方法是不行的,因为这样生成的几个数总有 n - 1 个是小于等于 total / n 的,但这不是所有的情况,比如 [ 1, 33, 33, 33 ] 就不能用 6 楼的方法生成出来。
当sum=10的时候,因为随机的还是0~100的整数,那这时候,随机生成的数中10~100之间的数,因为都>=10,所以最后的结果只能是10。而这时候,结果=10和 结果=小于10的某一个数的概率就完全不等了。所以这样的算法完全不行。如果要改的话,应该是 int n = r.nextInt(sum)+1;我的想法是。随机生成一个区间的数,然后把这个数随机的加到数组中的某一个数上面。
private static int[] getRandomArray(int size) {
int[] percent = new int[size];
Arrays.fill(percent, 1);//保证最小的数==1
int s = 100 - size;
int k = 5;//常数,==1比较平均的分配,越大越不平均。
Random r = new Random();
while (s > 0) {
int x = r.nextInt(size);
int y = r.nextInt(k > s ? s : k) + 1;
percent[x] += y;
s -= y;
}
return percent;
}
public static void go() {
Random r = new Random();
List<Integer> list = new ArrayList<Integer>();
int sum = 0;
while (true) {
int t = 0;
while (t == 0) {
t = r.nextInt(100);
}
sum += t;
if (sum == 100) {
list.add(t);
System.out.println(list);
return;
}
if (sum < 100) {
list.add(t);
}
if (sum > 100) {
sum = 0;
list.clear();
}
}
} public static void main(String[] args) {
for (int i = 0; i < 10; i++)
go();
}