我想模拟使用1到6的随机数生成器滚动两个骰子,然后将这两个值加在一起,我需要将它设置为循环,这样做一百万次。获取值后,我需要显示每个数字的总和。我该怎么做?我是在正确的轨道上吗?我一直把核心丢弃,所以我认为这是一个记忆问题。
以下是我想要遵循的文字: “假设你有一个游戏,你掷两个骰子,遵循这些规则: 第1-11卷:获得该值 第12轮:重新比赛并在值上加1 “滚动12”规则可以多次命中。例如,如果你滚(6,6)然后(6,6)然后(1,1), 你对该游戏的总价值将是4(1 + 1 + 2 = 4)。编写一个模拟这个游戏的一次迭代的程序。 然后写一个循环来运行这个游戏1,000,000次,跟踪你看到的每个值的数量,然后显示显示每个值的结果以及你获得该值的百分比。
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std;
int main ()
{
int i, k, l, y, ncount;
k=0;
l=0;
y=0;
int R[1000000];
int T[1000000];
int S[1000000];
srand(time(NULL));
for (i=0; i<1000000; i++)
{
R[k] = (rand() % 6 + 1);
T[l] = (rand() % 6 + 1);
S[y] = R[k] + T[l];
k++;
l++;
y++;
}
ncount = count (S, S+1000000, 1);
cout << "1 appears " << ncount << " times.\n";
return 0;
}
答案 0 :(得分:1)
我喜欢这个 - 非常可爱 - 实验。
这里有一些你不能使用的代码示例(它使用各种库的东西和C ++ 14的优点,你的课程绝对不会允许,从统计学上讲,如果你把它转过来会引起很多人的关注在)。
然而,它可以作为灵感,并验证您的无偏差随机数生成和正确的统计数据!
<强> Live On Coliru 强>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <iomanip>
#include <iostream>
#include <random>
namespace ba = boost::accumulators;
namespace bat = ba::tag;
using namespace std;
static mt19937 engine { random_device{}() };
static uniform_int_distribution<unsigned> dist(1, 6);
auto single() {
return dist(engine);
}
auto dual() {
auto a = single(), b = single();
//cout << "Rolled (" << a << ", " << b << ")\n";
return a + b;
}
auto magic_roll() {
int eyes, extra = 0;
while (12 == (eyes=dual()))
extra += 1;
return extra + eyes;
}
int main() {
ba::accumulator_set<unsigned, ba::stats<bat::mean, bat::variance> > stats;
constexpr auto N = 15;
size_t histo[N] = { 0 }; // allow for quite extreme outliers
for (size_t i = 0; i < 1'000'000; ++i) {
auto score = magic_roll();
//cout << "score: " << score << "\n";
stats(score);
assert(score >= 2 && score < N);
++histo[score];
}
cout << "Mean: " << ba::mean(stats) << "\n";
cout << "Std Deviation: " << sqrt(ba::variance(stats)) << "\n";
auto peak = *max_element(begin(histo), end(histo));
auto scale = [peak](auto v) { return v * 60.0 / peak; };
auto bucket = 0;
for(auto v : histo)
{
cout << "Histo bucket: " << right
<< setw(2) << bucket++ << "\t"
<< setw(6) << v << " " << string(scale(v), '*') << "\n";
}
}
输出
Mean: 6.88604
Std Deviation: 2.29999
Histo bucket: 0 0
Histo bucket: 1 0
Histo bucket: 2 27806 *********
Histo bucket: 3 56229 *******************
Histo bucket: 4 84624 *****************************
Histo bucket: 5 113481 ***************************************
Histo bucket: 6 142361 **************************************************
Histo bucket: 7 170696 ************************************************************
Histo bucket: 8 143744 **************************************************
Histo bucket: 9 114814 ****************************************
Histo bucket: 10 86860 ******************************
Histo bucket: 11 57734 ********************
Histo bucket: 12 1611
Histo bucket: 13 39
Histo bucket: 14 1
答案 1 :(得分:0)
当我解释这个赋值时,它不需要大数组。
然后写一个循环来运行这个游戏1,000,000次,跟踪你看到的每个值中有多少,
请注意,您没有跟踪所看到的每一个值;你只是跟踪你看过多少次。
此外,你必须计算的价值只是你玩过&#34;&#34;之后的最终价值。游戏一次,也就是说,反复滚动两个骰子,直到你得到的东西不是双六。在给出的例子中,滚动(6,6),然后(6,6),然后(1,1),这两个骰子的三个滚动只是一个游戏,其最终值为4.因此,毕竟这些卷你会加1到你看过4次。
此游戏的数据存储只需要为游戏结束时可能获得的每个值存储一个整数。坏消息是游戏没有最大的理论价值 - 理论上你可能会一个接一个地滚动(6,6)任何次数,从而产生很高的游戏价值。 然而,在实践中,你不太可能连续几次滚动双六次。
一种众所周知的方法来保持每个值发生的次数,当可能实际发生的值的范围不是太大时,是分配一个比你拥有的最大值大一点的数组数数。如果您将数组命名为count
,则count[2]
是2发生的次数,count[3]
是3发生的次数,等等。
(如果您必须计算负数出现的次数,这不太方便,但在这种情况下您不必担心这一点。)
其他方式包括保存数字对的数据结构:每对的第一个数字是一个值,第二个数字是第一个数字发生的次数。数据结构可以是可以存储数字对的任何内容:您自己设计的链接列表,std::list
或std::map
。
但每次你玩#34;一个游戏,你必须搜索你的数据结构,看看之前是否发生过该游戏的价值,然后在该值发生的次数上加1,或者在数据结构中创建一对新的数字来计算首次出现该值。
然后显示显示每个值的结果以及获得该值的百分比。
换句话说,显示每个不同的值一次,沿着具有该值的游戏的百分比。 但是,为您要打印的每个值专门编写一些代码行通常不是一种好习惯,就像您在示例中所做的那样 值1出现的次数。
顺便说一句,请务必仔细阅读游戏说明。 您最初尝试对此进行编程将永远不会产生值13,但游戏可能会产生值13,甚至14或更高。 例如,(6,6),然后(6,6),然后(6,5)的滚动使得一场比赛的值为1 + 1 + 11 = 13.
另一个建议:不要创建多个不同命名的
你真的不需要的变量。
在您初次尝试此计划时,您有变量k
,l
和y
其唯一用途是索引数组R
,S
和T
。
当您为这些目的使用任何这些变量时,从不
任何这些变量的值是否会与i
不同。
你的循环写得更好
for (int i=0; i<1000000; i++)
{
R[i] = (rand() % 6 + 1);
T[i] = (rand() % 6 + 1);
S[i] = R[i] + T[i];
}
那个循环完全你的循环所做的事情,但它更清楚它是什么 当你以这种形式看到它时,确实会这样做。
然而,如上所述,更好的是不要写循环
通过这种方式:你确实需要for (int i=0; i<1000000; i++)
但不是循环内的东西。