【问题标题】:Random Number Program Using Function c++使用函数 c++ 的随机数程序
【发布时间】:2022-06-10 17:43:34
【问题描述】:

我创建了一个简单的随机数程序,它接受 5 个输入并输出不同的随机数。

用户可以输入 5 个元音,不考虑大小写,函数会根据输入计算一个随机数。

可能的收入:a A a A e

可能的结果:1 2 3 19 25

问题:当我多次输入同一个元音时,我没有得到不同的数字,但是当我设置断点并在调试器模式下运行我的代码时,情况就不一样了

以下是我的代码

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <iomanip>

using namespace std;

int createRandomFromChar(char inputChar);

int main()
{
    char answer;
   
    char inputOne, inputTwo, inputThree, inputFour, inputFive;

    cout << endl <<
        "This program plays a simple random number guessing game." << endl;

    do
    {
        cout << endl << "Enter 5 vowel characters (a,e,i,o,u or A,E,I,O,U) separated by spaces: ";
        cin >> inputOne >> inputTwo >> inputThree >> inputFour >> inputFive;
        cin.ignore();
       
        int randomNumberOne = createRandomFromChar(inputOne);
        int randomNumberTwo = createRandomFromChar(inputTwo);
        int randomNumberThree = createRandomFromChar(inputThree);
        int randomNumberFour = createRandomFromChar(inputFour);
        int randomNumberFive = createRandomFromChar(inputFive);
        

        cout << "The random numbers are " << left << 
            setw(3) << randomNumberOne << left <<
            setw(3) << randomNumberTwo << left <<
            setw(3) << randomNumberThree << left << setw(3) << randomNumberFour 
            << left << setw(3) << randomNumberFive;

       

        cout << endl << "Do you want to continue playing? Enter 'Y' or 'y' to continue playing: "
            << endl;
        
       
        answer = cin.get();

        cin.ignore();
    }
    while ((answer == 'y') || (answer == 'Y'));

}

int createRandomFromChar(char inputChar)
{
    srand(time(0));

    int n1 = 1 + (rand() % 20);
    int n2 = 21 + (rand() % 20);
    int n3 = 41 + (rand() % 20);
    int n4 = 61 + (rand() % 20);
    int n5 = 81 + (rand() % 20);

    if ((inputChar == 'a') || (inputChar == 'A'))
    {
        return n1;

    }
    else if ((inputChar == 'e') || (inputChar == 'E'))
    {
        return n2;

    }
    else if ((inputChar == 'i') || (inputChar == 'I'))
    {
        return n3;

    }
    else if ((inputChar == 'o') || (inputChar == 'O'))
    {
        return n4;

    }
    else if ((inputChar == 'u') || (inputChar == 'U'))
    {
        return n5;

    }
    else
    {
        return 0;
    }
    
}
 

【问题讨论】:

  • 这能回答你的问题吗? srand() — why call it only once?
  • time(0) 以秒为单位返回时间。在一秒钟内多次调用它会产生相同的种子和相同的随机序列。当您放置断点时,您会强制增加时间间隔,因此您将获得不同的种子。底线:您应该在调用createRandomFromChar 之前将srand(time(0)); 放入main()
  • 甚至比修复srand 更好——在 C++ 中,建议使用 实用程序。请参阅:en.cppreference.com/w/cpp/numeric/random

标签: c++


【解决方案1】:

当我多次输入同一个元音时,我没有得到不同的数字,但是当我设置断点并在调试器模式下运行我的代码时,情况就不一样了

因为这样:

int createRandomFromChar(char inputChar)
{
    srand(time(0));  // <- the culprit

每次调用createRandomFromChar 时,都会使用time(0) 返回的值重新设置(重新启动)伪随机数生成器。如果您在不单步调试器的情况下运行程序,它将在几微秒内运行程序,time(0) 每次都会返回相同的值 - 因此,您将在之后从rand() 获得相同的数字序列。当您单步调试调试器时,您可能会花时间,因此time(0) 将返回不同的值,这将导致来自rand() 的不同数字序列。

解决方案是在整个程序运行期间只调用std::srand(std::time(nullptr));一次。您可以在main 的开头执行此操作,然后再也不执行。



另一种选择是使用更好的伪随机数生成器之一,例如 std::mt19937,它是在 C++11 中添加到 C++ 的,以及与它们一起标记的发行版之一,例如 std::uniform_int_distribution。这些生成器非常快并且具有rand() 所没有的可移植统计属性。注意:您也应该在每个程序运行时只播种一次。

示例用法:

#include <array>
#include <cctype>
#include <iomanip>
#include <iostream>
#include <random>
#include <string_view>

// A better pseudo random number generator than using rand() (+ srand()). 
// This is here seeded by a call to an instance of `std::random_device`:
static std::mt19937 prng(std::random_device{}());

int createRandomFromChar(char inputChar) {
    // a string_view over the valid characters:
    static std::string_view chars{"aeiou"};

    // a distribution to turn random numbers into the range [1,20]:
    static std::uniform_int_distribution<int> dist(1, 20);

    // turn inputChar into lowercase:
    inputChar = static_cast<char>(std::tolower(static_cast<unsigned char>(inputChar)));

    // find the position of the inputChar in the string_view:
    if(auto pos = chars.find(inputChar); pos != std::string_view::npos) {
        // multiply the position in the string_view with
        // (dist.max() - dist.min() + 1) which is 20, so
        //  'a' becomes 0 * 20 => 0
        //  'e' becomes 1 * 20 => 20
        //  'i' becomes 2 * 20 => 40  etc...
        int letter_start = static_cast<int>(pos) * (dist.max() - dist.min() + 1);

        // get a random number in the range [1,20]:
        int randomNumber = dist(prng);

        // return the result:
        return letter_start + randomNumber;
    }

    // inputChar was not found in the string_view, return 0:
    return 0;
}

您还可以通过使用数组而不是单独的变量来稍微简化您的main

int main() {
    char inputs[5]; // all inputs

    std::cout
        << "Enter " << std::size(inputs)
        << " vowel characters (a,e,i,o,u or A,E,I,O,U) separated by spaces: ";

    // extract one char at a time:
    for(char& inp : inputs) {
        if(!(std::cin >> inp)) {
            std::cerr << "error in input, bye bye.\n";
            return 1;
        }
    }

    // all results:
    int rndNumbers[std::size(inputs)];

    for(size_t i = 0; i < std::size(inputs); ++i) {
        rndNumbers[i] = createRandomFromChar(inputs[i]);
    }

    std::cout << "The random numbers are ";
    for(int num : rndNumbers) {
        std::cout << std::left << std::setw(3) << num;
    }
    std::cout << '\n';
}

【讨论】:

    猜你喜欢
    • 2016-05-15
    • 2018-09-26
    • 2017-06-13
    • 2014-04-27
    • 2015-04-20
    • 2014-01-16
    • 2013-06-27
    • 2011-06-26
    • 1970-01-01
    相关资源
    最近更新 更多