关于骰子概率计算的一个C++问题
A C++ question about dice probability calculation
编写一个程序来找出每个概率 "总值"当几个无偏的不规则骰子(可能具有不同数量的 面孔(同时被抛出。
当掷出无偏骰子时,具有不同面值的概率应该 等同。例如,一个典型的立方骰子应该给出 1/6 的概率 值 1、2、3、4、5 和 6。 如果抛出两个立方骰子,则两个骰子上的面值之和在范围内 [2..12]但是,每个"总值"的概率并不相等。例如, 总计 4 的概率为 3/36(对于组合 1+3、2+2 和 3+3(,而 总共 2 的概率只有 1/36(当两个骰子都给出 1 时(。
Sample output as follow: (the one with * are the input from user)
Input the number of dice(s): *2
Input the number of faces for the 1st dice: *6
Input the number of faces for the 2nd dice: *6
Probability of 2 = 1/36
Probability of 3 = 2/36
Probability of 4 = 3/36
Probability of 5 = 4/36
Probability of 6 = 5/36
Probability of 7 = 6/36
Probability of 8 = 5/36
Probability of 9 = 4/36
Probability of 10 = 3/36
Probability of 11 = 2/36
Probability of 12 = 1/36
Input the number of dice(s): *5
Input the number of faces for the 1st dice: *1
Input the number of faces for the 2nd dice: *2
Input the number of faces for the 3rd dice: *3
Input the number of faces for the 4th dice: *4
Input the number of faces for the 5th dice: *5
Probability of 5 = 1/120
Probability of 6 = 4/120
Probability of 7 = 9/120
Probability of 8 = 15/120
Probability of 9 = 20/120
Probability of 10 = 22/120
Probability of 11 = 20/120
Probability of 12 = 15/120
Probability of 13 = 9/120
Probability of 14 = 4/120
Probability of 15 = 1/120
我实际上不知道如何完成概率部分。我想有一些关于计算问题的方法的提示。
#include <iostream>
#include <string>
using namespace std;
//Initialise output function
string output(int num){
case 1:
return "st";
break;
case 2:
return "nd";
break;
case 3:
return "rd";
break;
default:
return "th";
}
//Roll function
int roll(int num, int result, int value[20]){
int dice[num][20];
for (int i=0; i<num;i++){
for (int j=1; j<=value[i];j++){
for (int k=0; k<value[i];k++)
dice[i][k]=j;
}
}
}
}
int main(){
int number;
//Initialise the number variable
cout <<"Input the number of dice(s): ";
cin >> number;
cout<<endl;
//Initialise the face of the dice using std::array
int value[11];
for (int i=0; i<number; i++){
cout << "Input the number of faces for the "<< i+1 << output(i+1)
<<" dice: ";
cin>>value[i];
}
//set the base of the probability (multiply), the maxrange (sum) for
the dice probability
int base=1;
int sum;
for (int i=0; i<number; i++){
base = base*value[i];
sum = sum +value[i];
}
//Output statements
if (sum >9){
for (int i=number; i<10; i++){
cout << "Probability of "<<i<<" = "<<roll(number, i, value);
}
for (int i=10; i<=sum;i++){
cout << "Probability of "<<i<<" = "<<roll(number, i, value);
}
} else {
for (int i=number; i<=sum; i++){
cout << "Probability of "<<i<<" = "<<roll(number, i, value);
}
}
return 0;
}
您可以使用 brute froce 并使用递归函数计算所有组合,并使用映射来计算每个结果出现的数量。
此外,使用 C++ 容器而不是 C 样式数组。
喜欢:
#include <iostream>
#include <vector>
#include <map>
void calcAll(const uint32_t value,
const uint32_t index,
const std::vector<uint32_t>& dices,
std::map<uint32_t, uint32_t>& count,
uint32_t& total)
{
if (index == dices.size())
{
// No more dices -> save result and stop recursion
auto it = count.find(value);
if (it == count.end())
{
count[value]=1;
}
else
{
count[value]++;
}
++total;
return;
}
// Iterate over all dice values
for (uint32_t i = 0; i < dices[index]; ++i)
{
calcAll(value + i + 1, index + 1, dices, count, total);
}
}
int main() {
std::vector<uint32_t> dices {6, 6, 6}; // 3 dices, 6 sides each
std::map<uint32_t, uint32_t> count;
uint32_t total = 0;
calcAll(0, 0, dices, count, total);
for (const auto& v : count)
{
std::cout << v.first << " seen " << v.second << " times out of " << total << std::endl;
}
return 0;
}
输出:
3 seen 1 times out of 216
4 seen 3 times out of 216
5 seen 6 times out of 216
6 seen 10 times out of 216
7 seen 15 times out of 216
8 seen 21 times out of 216
9 seen 25 times out of 216
10 seen 27 times out of 216
11 seen 27 times out of 216
12 seen 25 times out of 216
13 seen 21 times out of 216
14 seen 15 times out of 216
15 seen 10 times out of 216
16 seen 6 times out of 216
17 seen 3 times out of 216
18 seen 1 times out of 216
对于 6 面骰子,您有一个"概率向量">
[1/6, 1/6, 1/6, 1/6, 1/6, 1/6]
然后对于每个额外的骰子,您将向量与下一个骰子的"概率向量"进行卷积,以获得更长、更"钟形"的向量。
[1/6, 1/6, 1/6, 1/6, 1/6, 1/6] * [1/6, 1/6, 1/6, 1/6, 1/6, 1/6] =
[1/36, 2/36, 3/36, 4/36, 5/36, 6/36, 5/36, 4/36, 3/36, 2/36, 1/36]
你可以这样编码:(请注意,我从卷积中分解了分母(。
static std::vector<int> conv(const std::vector<int>& f, const std::vector<int>& g) {
const int nf = f.size();
const int ng = g.size();
const int n = nf + ng - 1;
std::vector<int> out(n);
for(int i = 0; i < n; ++i) {
const int jmn = (i >= ng - 1) ? i - (ng - 1) : 0;
const int jmx = (i < nf - 1) ? i : nf - 1;
for(int j = jmn; j <= jmx; ++j) {
out[i] += (f[j] * g[i - j]);
}
}
return out;
}
static void rollDice(const std::vector<int>& dice) {
std::vector<int> firstDie(dice[0], 1);
std::vector<int> a = firstDie;
int denominator = dice[0];
for (int i = 1; i < dice.size(); ++i) {
a = conv(a, std::vector<int>(dice[i], 1));
denominator *= dice[i];
}
for (auto aa : a) {
std::cout << aa << '/' << denominator << 'n';
}
}
int main() {
rollDice({6, 6});
rollDice({1, 2, 3, 4, 5});
}
输出为:
1/36
2/36
3/36
4/36
5/36
6/36
5/36
4/36
3/36
2/36
1/36
1/120
4/120
9/120
15/120
20/120
22/120
20/120
15/120
9/120
4/120
1/120
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 运行同一解决方案的另一个项目的项目
- 挂起和取消挂起一个文件DLL
- 用C++中的一个变量定义一个常量
- 函数向量_指针有不同的原型,我可以构建一个吗
- 在c++中用vector填充一个简单的动态数组
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 预处理器:插入结构名称中的前一个行号
- 我在c++代码中生成了一个运行时#3异常
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 从链接列表c++中删除一个项目
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '