有一组数,共十个:1,2,... 10
要"随机"地分成两组,每组5个
并且两组数和之比在一区间内,比如(0.5,1.5)
比如一组为1,3,5,7,9,另一组为2,4,6,8,10
则两组数和之比是25/30=5/6问如何"随机"地分成两组?
要"随机"地分成两组,每组5个
并且两组数和之比在一区间内,比如(0.5,1.5)
比如一组为1,3,5,7,9,另一组为2,4,6,8,10
则两组数和之比是25/30=5/6问如何"随机"地分成两组?
不玩嘴皮子上那些虚的,看程序结果才是王道:
#include <stdio.h>
#include <iostream>
#include <cmath>
#include <ctime>using namespace std;int main() {
const int length = 15; // 数组长度
int array[length];
srand(time(0));
cout << "随机分配 " << length << " 个数" << endl;
for (int i = 0; i < length; i++) {
array[i] = rand() % 30; // 分配随机数
cout << array[i] << "\t";
}
int times = 20;
bool flag = true; // 如果flag为false,则混排成功
while (flag) {
for (int i = 0; i < times; i++) {
// 把数组中的数字顺序打乱
int k = rand() % length; // k为0~length-1
int temp = array[k];
array[k] = array[length - 1 - k];
array[length - 1 - k] = temp;
}
int sum1 = 0; // 前 length / 2 个数的和
int sum2 = 0; // 后 length - length / 2 个数的和
for (int i = 0; i < length / 2; i++) {
sum1 += array[i];
}
for (int i = length / 2; i < length; i++) {
sum2 += array[i];
}
float ratio = (float)sum1 / (float)sum2;
if (ratio > 0.5 && ratio < 1.5) {
flag = false;
// 输出混排后的数组元素
cout << endl << "混排成功后数组元素的顺序为:" << endl;
for (int i = 0; i < length; i++) {
cout << array[i] << "\t";
}
cout << endl << "前 " << length / 2 << " 个数之和与后 " << (length - length / 2)
<< "个数之和的比是 " << ratio << endl;
}
}
}随机分配 10 个数
28 29 2 27 16 4 21 19 22 14
混排成功后数组元素的顺序为:
14 29 2 21 16 4 27 19 22 28
前 5 个数之和与后 5个数之和的比是 0.82随机分配 15 个数
26 28 28 25 26 13 25 1 21 8
20 15 5 13 25
混排成功后数组元素的顺序为:
26 28 5 15 26 13 25 1 21 8
20 25 28 13 25
前 7 个数之和与后 8个数之和的比是 0.978723
随机分配 25 个数
10 17 15 11 28 0 24 2 17 4
22 29 6 2 11 23 23 20 19 28
24 7 14 22 26
混排成功后数组元素的顺序为:
26 17 14 7 24 0 19 20 17 23
22 2 6 29 11 4 23 2 24 28
28 11 15 22 10
前 12 个数之和与后 13个数之和的比是 0.896714
int length = 10;
cout << "输入length: " << endl;
cin >> length;
int* array = NULL;
array = new int[length];
.
.
.
delete[] array;
回Inhibitory:我的十个数是1,2...10,你为何改成其他数?偶看这样行吗:先随机分成两组,如果比值不在区间内(由于第一组数偏大),则在第一组中"任"选一个较大的数与第二组中"任"一个较小的数交换,如果还不行,再换问题:以上算法会使比值落在区间边界附近的可能性偏大如何改进?
2: 生成随机数,范围0~9,取整;
3: 临时下标=生成的随即数
4: 按临时下标从数组取数字
5: 如果该数字是0,临时下标++,临时下标除10取余,回到4
6: 如果该数字不是0,表示成功获得,把数字保存到另一个数组A,同时把原数组里该位置置0
7: 重复5次
8: 遍历一遍原数组,把非零的数字保存到数组BA B就是随机分出的数组
1: 把10个数放 到数组里,初始范围 max=10;
2: 生成随机数,范围0~max,取整;
3: 临时下标=生成的随即数
4: 交换临时下标和下标是max的数据;
5: max--;
6: 重复2~5 次前5个和后5个分别就是 需要的两组数据
========================================================1。1 到 k 的数,和为 sum,分成两组,它的比率在 (d1, d2) 之间,就可以获得它们每组和的最大值和最小值。 min = (int) (sum / ((1 + d1) / d1));
max = (int) (sum / ((1 + d2) / d2));2。按照楼主所说的,先进行随机分组,求出其中一组的和,或它的和在 (min, max) 之间,就OK 。否则,在 (min, max) 之间随机抽取一个数,得出差值,再与和小的一组小的最小值相加,再到另一组中寻找该数(为方便寻找可以限制正负范围),与那组中的最小值进行交换,若没有找到,继续在 (min, max) 之间随机抽取,重复上述过程。
float d2 = 1.5f; // 比率上限
int k = 10; // 数组个数
int sum = (1 + k) * (k / 2); // 数组和
int min = (int) (sum / ((1 + d1) / d1)); // 限定比率的最小和
int max = (int) (sum / ((1 + d2) / d2)); // 限定比率的最大和
System.out.println(min + " " + max); // 生成数字序列
int[] num = new int[k];
for (int i = 0; i < k; i++) {
num[i] = i + 1;
}
System.out.print("原数组:");
print(num); int[] group1 = new int[k / 2];
int[] group2 = new int[k / 2];
int groupSum = 0; // 存放某一组的和
Random random = new Random();
// 若 groupSum 不在 (min, max) 范围内,则重新分组
while (groupSum < min || groupSum > max) {
groupSum = 0; // 通过随机数交换数字,交换次数、交换位数都是随机
int r = random.nextInt(k * 2);
for (int i = 0; i < r; i++) {
int r1 = random.nextInt(k);
int r2 = random.nextInt(k);
int tmp = num[r1];
num[r1] = num[r2];
num[r2] = tmp;
}
System.out.print("交换后:");
print(num); // 进行分组,并统计一组的和
for (int i = 0; i < k / 2; i++) {
group1[i] = num[i];
groupSum += num[i];
group2[i] = num[i + k / 2];
}
System.out.print("第一组:");
print(group1);
System.out.print("第二组:");
print(group2);
System.out.println("一组和:" + groupSum);
System.out.println("二组和:" + (sum - groupSum));
System.out.println("比 率:" + groupSum / ((float) sum - groupSum));
}
} public static void print(int[] ns) {
for (int i : ns) {
System.out.printf("%3d", i);
}
System.out.println();
}
}