`

将一个整数S随机拆分为在min~max之间的整数之和,并将分配结果存储到数组K中【修正版】

    博客分类:
  • java
 
阅读更多
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之间的整数.txt

    本篇文章主要介绍如何将一个整数S随机拆分成N个在指定范围[min, max]内的整数。该问题通常应用于统计学模拟、游戏开发等领域,对于实现数据的合理分配具有一定的实际意义。 #### 二、核心算法思想 要解决这个问题,...

    MAX SUM 给定由n整数(可能为负数)组成的序列 {a1,a2,…,an},求该序列形如ai+ai+1,…,+aj的子段和的最大值。当所有的整数均为负数时定义其最大子段和为0。

    根据题目要求,我们面对的是一个经典的编程问题:求解给定整数序列中的最大子段和。本题目的核心在于如何高效地找到一个序列中所有连续子序列的最大和。如果序列中的所有元素都是负数,则最大子段和定义为0。 ### ...

    C语言常用算法程序汇总.pdf

    定义一个数组`a`来存储结果,使用反向遍历的方式,每次将整数`n`除以10得到余数并存入数组,同时将`n`更新为其除以10的结果。当`n`变为0时,拆分完成。 3. 求整数的因子之和: 这个算法通过遍历从1到输入整数`n`,...

    2_numpy_python数组_

    在Python编程语言中,NumPy库是一个至关重要的组成部分,它为高效地处理大型多维数据提供了支持。NumPy,全称为“Numerical Python”,它的核心是`ndarray`对象,这是一个用于存储同类型元素的多维数组。这个库极大...

    VBA典型试题-及答案.doc

    这个问题展示了如何使用`Rnd`函数生成0到1之间的随机数,并通过`Fix`函数将其转换为10到100之间的整数。通过`If...Then`语句,统计不同区间内的整数个数。 2. 计算随机整数的最大值、最小值和平均值: 在这个例子...

    动态规划实现多边形游戏.pdf

    我们可以创建一个三维数组 m[i][j][0] 来存储每个顶点的最小值和最大值。其中,m[i][j][0] 代表从 i 到 j 的最小值,m[i][j][1] 代表从 i 到 j 的最大值。 我们可以使用递归函数 minmax(i, j, s) 来计算从 i 到 j ...

    SQL Server 查询两个日期之间的所有月份

    在给定的代码示例中,`@min`和`@max`分别存储了起始和结束日期的字符串格式,它们将在后续的查询中使用。 代码的核心部分在于创建一个动态SQL语句,利用`master.dbo.spt_values`系统表中的数字列生成日期范围。`spt...

    非常有趣的C语言算法

    考虑到闰年的情况,程序使用一个预定义的`day_tab`数组存储每个月的天数,并进行适当调整。 8. **杨辉三角** (Huijiao.c) 杨辉三角是一种数字模式,每个数是上一行相邻两数的和。程序初始化一个矩阵,并填充杨辉...

    达内 coreJava 习题答案

    其中a为1至9之中的一个数,项数也要可以指定。 import java.util.Scanner; class Multinomial{ public static void main(String[] args){ int a; //定义输入的 a int howMany; //定义最后的一项有多少个数字 ...

    C语言教程课件Ch08函数-2.ppt

    在上面的示例中,`dif`、`max`和`min`函数都接收三个整数参数,并返回一个整数值。 4. **函数的调用**:在函数调用时,会将控制权转移给被调用的函数,并且可以传递参数。例如,`main()`函数调用`dif()`函数计算三...

    c++课程非常经典的ppt

    - **快速排序**:通过选取一个“基准”元素,将数组分为小于和大于基准的两部分,然后对这两部分分别进行排序。 - **归并排序**:将数组拆分成两半,分别排序后再合并,保证排序正确性。 - **大整数乘法**:如...

    算法面试经典 100题

    - 遍历数组,每遇到一个新元素就将其加入堆中,若堆的大小超过k,则弹出堆顶元素。 - 最终堆中的元素即为最小的k个元素。 #### 6. 腾讯排数 **知识点**:本题考查如何解决一种特殊类型的数学谜题。 **解题思路**:...

    numpy知识点总结.7z

    Numpy是Python编程语言中的一个核心库,专用于数值计算和大型多维数组处理。它在科学计算领域扮演着至关重要的角色,为高效的数据操作提供了强大的工具。以下是对Numpy的一些关键知识点的详细总结: 1. **数组对象...

    做个vb程序验证哥德巴赫猜想(有源码)

    2. **质数生成**:生成一定范围内的所有质数,并存储在一个数组或列表中。 3. **拆分逻辑**:遍历质数数组,寻找两个质数的和等于目标偶数的组合。 4. **用户交互**:可能包含输入框让用户输入要验证的偶数,以及...

    华为机考题

    - 维护一个最小价格变量min_price和一个最大收益变量max_profit。 - 遍历每一天的股票价格,更新min_price和max_profit。 - 输出最优解,包括买入天数、卖出天数和收益。 ### 总结 以上三个问题分别涉及到了数据...

    numpy_practice_numpy_

    在Python的科学计算领域,NumPy是一个不可或缺的库,它为高效处理大型多维数组和矩阵提供了强大的支持。本练习集“numpy_practice”旨在帮助用户深入理解和掌握NumPy的功能和用法,无论你是初学者还是希望提升技能的...

    Numpy学习指南代码

    NumPy是Python编程语言中的一个核心库,专用于数值计算和大规模数据处理。它提供了多维数组对象(ndarray),以及一系列高效的数学函数来操作这些数组。本学习指南的代码涵盖了多个章节,包括ch1到ch11,每个章节...

    matlab第三章课后部分答案.pdf

    - `input`函数用于从键盘接收用户输入的数据,例如在3-2题中通过`input('请输入一个三位整数:')`获取三位整数。 - `fix`函数用于截取变量的小数部分,返回整数部分。 - `rem`函数是取余运算,可以得到两个数相除...

    100道numpy练习题

    【numpy】是Python编程语言中的一个核心库,全称为Numerical Python,主要用于处理大型多维数组和矩阵。它为高性能科学计算提供了强大的工具,广泛应用于数据科学、机器学习、图像处理等领域。本压缩包包含的"100道...

    python numpy 的一些基本操作和结果展示.zip

    NumPy提供了一系列统计函数,如`mean()`, `std()`, `min()`, `max()`,可用于计算数组的平均值、标准差、最小值和最大值: ```python print(np.mean(arr, axis=0)) # [2.5 3.5 4.5] print(np.std(arr, axis=1))...

Global site tag (gtag.js) - Google Analytics