生成1-n的不重复的随机数,1-n都会出现

1.让我们先来看一种粗暴的解法

 

​
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 100
int main() {
	int i, j, flag, num, a[N];
	srand((unsigned)time(NULL));
	for (i = 0; i < N; ++i) {
		num = rand() % N + 1;
		flag = 1;
		for (j = 0; j < i; ++j) {//判断前面是否出现过这个随机数,如果没有就加入结果中,如果出现过就继续产生随机数
			if (num == a[j]) {
				flag = 0;;
				break;
			}
		}
		if (flag) a[i] = num;
		else --i;
	}
	for (i = 0; i < N; ++i)
		printf("%d ", a[i]);
	printf("\n");
    while(1);
	return 0;
}

​

当N很小时,可能很快出结果,但是当N很大时运行很长时间都不一定能出结果。假设要产生1-100的随机数,某个时刻已经产生了1-99的数,但是还差1个100,然后程序继续运行,但是程序运行期间很可能很长一段时间都是产生和前面重复的数(1-99),这时候程序运行很长时间都不能得到想要的结果,这种方法有很大的运气在里面,所以不建议这种方法。

 

2.让我们再看一种改进后的做法

int *rand1(const int n) {
        vector<int> a;
        int *result = new int[n]; //保存结果的
        srand(static_cast<unsigned int>(time(nullptr)));
        for (int i = 0; i < n; ++i) a.push_back(i + 1);
        for (int i = 0; i < n; ++i) {
                int mark = rand() % (n - i);//获取下标
                result[i] = a[mark];
                swap(a[mark], a[n - i - 1]);
        }
        return result;

}

当输入为50时的结果

3 13 18 15 49 16 9 32 30 43 4 11 39 23 20 24 42 34 1 45 21 33 50 40 26 27 38 35 19 14 10 25 28 44 47 8 6 29 12 22 7 5 46 41 48 31 2 17 37 36  

上面这种做法能保证时间复杂度为O(n),但是用了双倍的空间。再看看下面只用一倍空间的做法。

 

3.2的改进

int *rand1(const int n) {
        int *a = new int[n];
        srand(static_cast<unsigned int>(time(nullptr)));
        for (int i = 0; i < n; ++i) a[i] = i + 1;
        for (int i = n-1; i > 0; --i) {//从最后面开始遍历,因为我们能控制产生的随机数范围
                int mark = rand() % i;//获得下标
                swap(a[mark], a[i]);//交换两个元素,交换过后a[i]的值就确定了
        }
        return a;
}
27 46 11 9 43 3 2 25 10 34 20 6 24 26 8 22 7 42 35 33 32 29 44 28 48 31 30 45 47 13 1 49 4 37 15 5 50 17 36 38 39 21 19 41 18 23 40 14 12 16

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值