如何将随机数组值一起添加到另一个数组中,然后在计算出现的值的同时显示它们? C++
How do add random array values together into another array and then display them while counting how many values appear? C++
我想使用从 1 到 6 的随机数生成器模拟掷两个骰子,然后将这两个值加在一起,我需要将其设置为循环执行一百万次。获取值后,我需要显示每个数字出现的总和数。我该怎么做?我在正确的轨道上吗?我一直在转储我的核心,所以我认为这是一个内存问题。
这是我应该遵循的文本:
“假设你有一个游戏,你掷两个骰子,遵循以下规则:
投掷 1-11:获得该值
第 12 卷:重新掷骰并将值加一
“roll 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;
}
我喜欢这个 - 非常可爱 - 实验。
这是一段您不能使用的示例代码(它使用了您的课程绝对不允许的各种库内容和 C++14 优点,从统计学上讲,如果您上交了)。
但是它可以作为灵感并验证您的无偏差随机数生成和正确的统计数据!
#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
在我解释这个赋值时,它不需要大数组。
Then write a loop that runs this game 1,000,000 times, keeping track of how many of each value you saw,
请注意,您没有跟踪看到的每个值;您只需记下看过多少次。
此外,您要计算的值只是您"played"玩过一次游戏后的最终值,即反复掷两个骰子,直到得到不是双六的点数。在给出的示例中,掷 (6,6),然后掷 (6,6),然后掷 (1,1),两个骰子的这三掷只是一场游戏,其最终值为 4。因此,毕竟这些卷你会在你看到 4 的次数上加 1。
该游戏的数据存储只需要为您在游戏结束时可能获得的每个值存储一个整数。坏消息是该游戏没有最大理论价值——理论上,您可能会一个接一个地掷出 (6,6) 任意次数,从而导致游戏的价值很高。
然而,在实践中,您不太可能连续多次掷出双六。
当实际可能出现的值的范围不太大时,一种记录每个值出现次数的众所周知的方法是分配一个比最大值稍大的数组你必须数数。如果将数组命名为 count
,则 count[2]
是 2 出现的次数,count[3]
是 3 出现的次数,依此类推。
(如果你必须计算负数出现的次数,这就不太方便了,但在这种情况下你不必担心。)
其他方法包括保存数字对的数据结构:每对数字的第一个数字是一个值,第二个数字是第一个数字出现的次数。数据结构可以是任何可以存储数字对的东西:您自己设计的链表、std::list
或 std::map
。
但是每次你 "play" 一个游戏你必须搜索你的数据结构以查看该游戏的值之前是否出现过,然后将 1 加到该值出现的次数,或者创建一个新的对数据结构中的数字数量来计算该值的第一次出现。
then display the results showing every value and what percent of the time you got that value.
换句话说,显示每个不同值一次,以及具有该值的游戏的百分比。
但是,专门为要打印的每个值编写一些代码行通常不是很好的做法,就像您在示例中展示的那样
值 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++)
但不是循环内的东西。
我想使用从 1 到 6 的随机数生成器模拟掷两个骰子,然后将这两个值加在一起,我需要将其设置为循环执行一百万次。获取值后,我需要显示每个数字出现的总和数。我该怎么做?我在正确的轨道上吗?我一直在转储我的核心,所以我认为这是一个内存问题。
这是我应该遵循的文本: “假设你有一个游戏,你掷两个骰子,遵循以下规则: 投掷 1-11:获得该值 第 12 卷:重新掷骰并将值加一 “roll 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;
}
我喜欢这个 - 非常可爱 - 实验。
这是一段您不能使用的示例代码(它使用了您的课程绝对不允许的各种库内容和 C++14 优点,从统计学上讲,如果您上交了)。
但是它可以作为灵感并验证您的无偏差随机数生成和正确的统计数据!
#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
在我解释这个赋值时,它不需要大数组。
Then write a loop that runs this game 1,000,000 times, keeping track of how many of each value you saw,
请注意,您没有跟踪看到的每个值;您只需记下看过多少次。
此外,您要计算的值只是您"played"玩过一次游戏后的最终值,即反复掷两个骰子,直到得到不是双六的点数。在给出的示例中,掷 (6,6),然后掷 (6,6),然后掷 (1,1),两个骰子的这三掷只是一场游戏,其最终值为 4。因此,毕竟这些卷你会在你看到 4 的次数上加 1。
该游戏的数据存储只需要为您在游戏结束时可能获得的每个值存储一个整数。坏消息是该游戏没有最大理论价值——理论上,您可能会一个接一个地掷出 (6,6) 任意次数,从而导致游戏的价值很高。 然而,在实践中,您不太可能连续多次掷出双六。
当实际可能出现的值的范围不太大时,一种记录每个值出现次数的众所周知的方法是分配一个比最大值稍大的数组你必须数数。如果将数组命名为 count
,则 count[2]
是 2 出现的次数,count[3]
是 3 出现的次数,依此类推。
(如果你必须计算负数出现的次数,这就不太方便了,但在这种情况下你不必担心。)
其他方法包括保存数字对的数据结构:每对数字的第一个数字是一个值,第二个数字是第一个数字出现的次数。数据结构可以是任何可以存储数字对的东西:您自己设计的链表、std::list
或 std::map
。
但是每次你 "play" 一个游戏你必须搜索你的数据结构以查看该游戏的值之前是否出现过,然后将 1 加到该值出现的次数,或者创建一个新的对数据结构中的数字数量来计算该值的第一次出现。
then display the results showing every value and what percent of the time you got that value.
换句话说,显示每个不同值一次,以及具有该值的游戏的百分比。 但是,专门为要打印的每个值编写一些代码行通常不是很好的做法,就像您在示例中展示的那样 值 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++)
但不是循环内的东西。