rand和srand和bug

rand()和srand()

rand和srand,是C++中常用的随机数生成函数伪随机数生成函数
其中 rand()函数不需要输入参数,它会返回0到RAND_MAX之间的任意的整数。如果我们想他返回[0,n-1]内的整数,我们可以写:

int x = rand()%n;

返回[0,1]

double x = rand()/RAND_MAX;;

但是,每当我们重新运行一次,得到的X的值总是保持一致,他们一开始随机的起点总是一致的,这是我们不想看到的,于是就有了srand()来引入不同随机种子的函数。
我们通常用time(0)来作为随机种子。即:

srand(time(0));
int x = rand();

time(0)会返回从1970 UTC Jan 1 00:00到现在时间的秒数,类型为unsigned int。所以每次运行会传入不同的种子,使得随机数不同,但这样还是一个伪随机数

bug

当srand(time(0)),这个函数在一秒内反复执行的时候,它将不会更新随机数种子导致,rand()会一直生成一样的随机数,导致无法产生随机数,注意。

例题举例

参考例题:LeetCode528. 按权重随机选择
以下两种代码:代码1能过,后面的不行。

class Solution {
public:

    long long  sum = 0,n;
    long long  pre[100005] = {0};
    vector<int> cw;
    Solution(vector<int>& w) {
        sum = pre[0] = w[0];
        cw.push_back(w[0]);
        for(int i=1;i< w.size();i++){
            pre[i] += pre[i-1] + w[i];
            cw.push_back(w[i]);
            sum += w[i];
        }
        n = w.size()-1;
        srand((int)time(0));
    }
    
    int pickIndex() {
        int x = rand()%sum +1;
        for(int i=0;i<cw.size();i++){
            long long  left = pre[i] - cw[i] +1;
            long long  right = pre[i];
            if (x>= left && x<= right){
                return i;
            }
        }
        return 12123;
        //return lower_bound(pre[0],pre[n],x) - pre[0] - 1;
    }
};

/**
 * Your Solution object will be instantiated and called as such:
 * Solution* obj = new Solution(w);
 * int param_1 = obj->pickIndex();
 */

代码2,无法通过,因为此处的srand会在一秒内被反复调用,导致随机数种子失效。

class Solution {
public:

    long long  sum = 0,n;
    long long  pre[100005] = {0};
    vector<int> cw;
    Solution(vector<int>& w) {
        sum = pre[0] = w[0];
        cw.push_back(w[0]);
        for(int i=1;i< w.size();i++){
            pre[i] += pre[i-1] + w[i];
            cw.push_back(w[i]);
            sum += w[i];
        }
        n = w.size()-1;
    }
    
    int pickIndex() {
        srand((int)time(0));
        int x = rand()%sum +1;
        for(int i=0;i<cw.size();i++){
            long long  left = pre[i] - cw[i] +1;
            long long  right = pre[i];
            if (x>= left && x<= right){
                return i;
            }
        }
        return 12123;
        //return lower_bound(pre[0],pre[n],x) - pre[0] - 1;
    }
};

/**
 * Your Solution object will be instantiated and called as such:
 * Solution* obj = new Solution(w);
 * int param_1 = obj->pickIndex();
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值