package core.util; import java.util.Random; public class NumberRandDivideUtils { /** * 将一个整数summary随机拆分为N个在min~max之间的整数之和,并将分配结果存储到数组k中 * 注意:min~max之间差越大,则越容易随机分配,反之,差越小,分配越困难,甚至无解 * eg:min:5,max:8,summary:20,可以看出5 * +5+5+5+5=20,6+6+8=20,7+7+6=20,5+7+8=20,但使用随机数5~8,可能 * 第一次取到8,第2次也取到8,接下来无论怎么分配,也不可能为20 int min = 5; int max = 6; int summary =20; * @MODIFY 缩减分配与叠加分配共用后完美解决 */ public static int[] randDivide(int min, int max, int summary) { int maxl = summary % min == 0 ? summary / min : summary / min + 1; int[] k = new int[maxl]; // l:用来记录数组k中存储值的最后索引 int l = 0; int total = 0; if (min == max) {// 如果两数相等,则常数 if (summary % min == 0) { for (int i = 0; i < k.length; i++) { k[i] = min; } } } else { Random rand = new Random(); int remainder; for (int i = 0; i < k.length; i++) { // 剩余数 remainder = summary - total; // 如果剩余数在min与max之间,则跳出去直接设置k[++l]为余数 if (remainder >= min && remainder <= max) { k[i] = remainder; break; } else if (remainder < min) { // 数组最小长度 int minl = summary % max == 0 ? summary / max : summary / max + 1; // 如果i<最小数组长度,则缩减分配 if (i < minl) { k[i] = remainder; l = i; randDivideLessenFiller(summary, min, k, l); break; } else {// 如果i>=最小数组长度,做叠加分配 randDivideRemainder(summary, max, k, l, remainder); break; } } // 产生一个在min与max之间的随机数 int rd = rand.nextInt(max - min + 1) + min; k[i] = rd; total += rd; l = i; } } // 校验数组中的和不等于summary则返回0 int t = 0; for (int i = 0; i < k.length; i++) { if(k[i]<min||k[i]>max) break; t += k[i]; } if (t != summary) { return null; } return k; } private static void randDivideLessenFiller(int summary, int min, int[] k, int l) { if (summary / (l + 1) < min) return; Random rand = new Random(); // 最小值与平均数之间的一个随机数 int rv = rand.nextInt(summary / (l + 1) - min + 1) + min; int r = rv - k[l]; int j = 0; while (r > 0 && j < 1000) { int i = rand.nextInt(l); if (k[i] - r >= min) { k[i] -= r; k[l] += r; break; } int _r = rand.nextInt(r) + 1; if (k[i] - _r >= min) { k[i] -= _r; k[l] += _r; r -= _r; } j++; } } /** * l:数组最后的长度 r:余数 d:控制随机分配深度,j值一般达不到1000,防止无解导致栈溢出 */ private static void randDivideRemainder(int summary, int max, int[] k, int l, int r) { if (summary / (l + 1) > max) return; Random rand = new Random(); int j = 0; while (r > 0 && j < 1000) { int i = rand.nextInt(l); if (k[i] + r <= max) { k[i] = k[i] + r; break; } int _tempMax = rand.nextInt(max - summary / (l + 1) + 1) + summary / (l + 1); for (int t = 0; t <= l; t++) { if (k[t] < _tempMax) { // 最大数为程序要求的区间最大数-k[i],即空间与余数作比较 int _max = (_tempMax - k[t]) < r ? (_tempMax - k[t]) : r; if (_max == 0) continue; // 这里仍用随机数,而不是自动填补的原因是,不让数字整齐 int rn = rand.nextInt(_max) + 1; k[t] += rn; r -= rn; } } j++; } } }
相关推荐
将一个整数S随机拆分为N个在min~max之间的整数
这种类型的对象可以存储10个20~80之间的整数,即他的内部有一个整型数组存储数据。编程: (1) 判断两个inergerSet类对象S1和S2是否相等。提示:集合相等的前提是所有元素相等。 (2) 输出两个集合对象的交集。 ...
整数拆分整数拆分整数拆分整数拆分整数拆分整数拆分整数拆分整数拆分
我们使用Python的random模块生成了两个随机数组,分别是1到36中随机选取的5个数和1到12中随机选取的2个数。然后,我们使用加号运算符将这两个数组组合成一个新的数组,并输出结果。 需要注意的是,我们使用了random...
由N个有序整数组成的数列已放在一维数组中,给定程序MODI1.C中函数fun的功能是:利用折半查找整数m在数组中的位置。若找到,返回其下标值;反之,返回-1。 折半查找的基本算法是:每次查找前先确定数组中待查的范围...
数组a中已存有互不相同的10个整数从键盘输入一个整数,找出与该值相同的数组元素下标。 (如果没找到,输出“没找到”).c
TIA博途-整数拆分到字节数组中-全局FC库文件-V15版本
从键盘读入8个整数存入数组a中并输出这8个数据。 ⑴求出这8个数据的和、最大值、最小值及平均值。 ⑵求这8个数据的正数之和、负数之和(或正数与负数的个数); ⑶求这8个数据的奇数之和、偶数之和(或奇数与偶数的...
用数组定义,随机输入100以内整数,然后倒序输出.
有1个包含N个整数的数组A,定义1个数组的美丽值为数组中所有不同整数的和。求数组A的所有连续子序列的美丽值之和。
写一个程序。要求用户输入10个数据到数组中,然后将数组中最大值和最小值显示出来,并显示下标。C++小练习,适合新手学习数组、循环等概念。
C语言程序设计-产生20个[30,120]上的随机整数放入二维数组a[5][4]中, 求其中的最小值
将一个整数线性表拆分成奇数和偶数线性表,课后习题,完整好用
易语言整数到字节数组源码,整数到字节数组,十到十六,到十六进制文本
C语言程序设计-从键盘为一维整型数组输入10个整数,调用fun函数找出其中最小的数,并在main函数中输出;本.cC语言程序设计-
请在DOS命令窗口里编译运行该程序 dos下相关命令 编译:javac 文件名.java 运行:java 文件名 此处填写数字(每个数字要用空格隔开)
在主函数中输入10个整数到数组中,调用函数move()完成将数组元素循环移动k位(要求函数参数为:1数组名;2数组元素个数;3循环移动的位数k)。当k>0时,实现循环右移;当k时,实现循环左移。循环右移一位的意义是:将...
C语言程序设计-产生20个[30,120]上的随机整数放入二维数组a[5][4]中,求每行元素的和.txt
定义一个将数组元素输出到屏幕的函数,函数的参数也是数组类型,函数命名为OutputArray; 定义main函数,在其中定义并初始化arrayorder数组,然后分别钓用InputArray函数输入新的数组元素的值,然后调用SortArray...
输入一个数是不是在这个数组中,数组的循环输出