首页 > 解决方案 > 一个关于骰子概率计算的C++问题

问题描述

编写一个程序,找出同时抛出几个无偏的不规则骰子(可能具有不同数量的面)时每个“总值”的概率。

当掷出无偏骰子时,具有不同面值的概率应该相等。例如,一个典型的立方​​体骰子应该给出面值 1、2、3、4、5 和 6 的 1/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;
}

标签: c++probabilitydice

解决方案


您可以使用 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

推荐阅读