c语言扔骰子随机数的相加,【c/c 学习心得】运用rand()产生随机数,教你仿真模拟不合理的摇骰子...

哈啰~ 大家好, 今天教大家如何用函式库里面的rand()函数产生随机数, rand()的效果可以产生从0~RAND_MAX(int的最大值)之间的随机整数, 譬如说这...

哈啰~ 各位好!,

今日教大伙儿怎样用函式库里边的rand()涵数产生随机数,

rand()的实际效果能够 造成从0~RAND_MAX(int的最高值)中间的任意整数金额,

譬如说这支程序能够 造成十个随机数字:

#include

#include

using namespace std;

int main() {

for(int i = 0 ; i < 10 ;i ){

cout << rand() << endl;

}

return 0;

}

結果:

1804289383

846930886

1681692777

1714636915

1957747793

424238335

719885386

1649760492

596516649

1189641421

每一次实行程序的結果都一样?

奇妙的事儿发生了,

你能发觉,你每一次再次实行程序的情况下,

都一样是造成这十个数据,

咦咦? 即然都造成固定不动的数据,这数据一点也不任意呀?

并不是预估每一次再次实行程序的随机数字必须不一样吗?

缘故是那样的

因为电脑上事实上并没有办法自身造成「真实的乱数」,只有通过複杂的数学课演算法模拟相近乱数的标值材料,而在仿真模拟乱数时,必须设置一个乱数種子,电脑上会依据这一乱数種子来测算出一连串的乱数,同样的乱数種子便会造成同样的乱数编码序列,因此假如要让造成的乱数每一次都不一样,就需要设置不一样的乱数種子。

(参考文献: C/C 应用 rand 涵数造成任意乱数课堂教学与範例程式码)

因此假如要让每一次实行程序的結果都不一样得话,

务必要设置不一样的乱数種子,

设置乱数種子的涵数为srand(int);

一般来说,会在程序再加srand( time(NULL));这一行,

让乱数種子以现在的时间做设置,

那样每一次实行程序的結果就不一样了

#include

#include /* 乱数相关函数 */

#include /* 時间相关函数 */

using namespace std;

int main() {

srand( time(NULL));

for(int i = 0 ; i < 10 ;i ){

cout << rand() << endl;

}

return 0;

}

此外,教大伙儿如果是要随意浮点数範围或者随意整数金额範围的随机数字怎幺写

0~1中间的任意浮点数

double x = (double) rand() / (RAND_MAX 1.0);

a~b中间的任意浮点数

double x = (b - a) * rand() / (RAND_MAX 1.0) a;

a~b中间的任意整数金额

int x = rand() % (b - a 1) a;

之上能够 从特定的範围概率大约平等的取下一个数,

那如果是要仿真模拟不合理的摇骰子怎幺办呢?

例如期待掷出1点的概率是掷出2~六点的2倍这类的。

这里恰好有一道题合适训练。

leetcode- 528. Random Pick with Weight

参照题型: leetcode- 528. Random Pick with Weight

文题: 让你一个列阵,列阵里的每一个数表明indexi出現的占比。

譬如说input = [1,2,2],那么你造成的随机数字就需要有1:2:2的概率造成0,1,2。

参照程序:

最先大家先做概率的累积,

譬如说input是[a,b,c]好啦,

累积概率便是[a,a b,a b c]。

构思便是造成一个[0,a b c)区段的随机数字,

若随机数字落在[0,a)就传回0,

随机数字落在[a,a b)就传回1,

随机数字落在[a b,a b c)就传回2

(好几个随机数字的情况再自主推导)

c 程序: 582ms, AC

class Solution {

public:

vector accu_prob;

Solution(vector& w){

accu_prob.resize(w.size());

accu_prob[0]= w[0];

for(int i=1 ;i

accu_prob[i]= accu_prob[i-1] w[i];

}

}

int pickIndex() {

int R = rand() % accu_prob.back();

for(int i =0 ; i

if(R

return i;

}

}

return accu_prob.size()-1;

}

};

/**

* Your Solution object will be instantiated and called as such:

* Solution* obj = new Solution(w);

* int param_1 = obj->pickIndex();

*/

可是这支程序现阶段也有挺大的提升室内空间,

倘若要查寻随机数字落在哪个区段,

用for迴圈渐渐地搜真是太用时了,

提议配搭「二分查找」的技术性

c 程序(二分查找): 18b250s, AC

class Solution {

//涵数作用: 传回在排列列阵中,第一个超过目标的部位

int firstGreaterEqual(vector& nums, int target) {

int left = 0, right = nums.size();

while (left < right) {

int mid = left (right - left) / 2;

if (nums[mid] <= target)

left = mid 1;

else

right = mid;

}

return right;

}

public:

vector accu_prob;

Solution(vector& w){

accu_prob.resize(w.size());

accu_prob[0]= w[0];

for(int i=1 ;i

accu_prob[i]= accu_prob[i-1] w[i];

}

}

int pickIndex() {

int R = rand() % accu_prob.back();

return firstGreaterEqual(accu_prob, R);

}

};

/**

* Your Solution object will be instantiated and called as such:

* Solution* obj = new Solution(w);

* int param_1 = obj->pickIndex();

*/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值