【问题标题】:Random Number Generator Within Given Range给定范围内的随机数生成器
【发布时间】:2014-02-25 17:01:15
【问题描述】:

我正在尝试编写一个程序,该程序使用一个函数在用户提供的范围内生成 10 个随机数。它似乎工作正常,除了返回的数字都是 1 的事实:

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int rand_int(int min, int max);

int main()
{
    int min, max;

    cout << "Hello user.\n\n"
         << "This program will generate a list of 10 random numbers within a 
         given range.\n"
         << "Please enter a number for the low end of the range: ";
    cin  >> min;
    cout << "You entered " << min << ". \n"
         << "Now please enter a number for the high end of the range: ";
    cin  >> max;

    while(min > max){
        cout << "Error: Your low number is higher than your high number.\n"
             << "Please reenter your high number, or press ctrl + c 
                 to end program.\n";
        cin  >> max;
        cout << endl;
    }

    for(int i = 0; i < 10; i++){
        int rand_int(int min, int max);
        cout << rand_int << endl;
    }

    return 0;
}


int rand_int(int min, int max)
{
    srand(time(0)); // Ensures rand will generate different numbers at different times

    int range = max - min;

    int num = rand() % (range + min);

    return num;
}

【问题讨论】:

  • 你应该回去阅读变量定义和函数调用。另外,不要每次都重新播种(尤其是不要在紧密循环中使用 time(0))。
  • 你能再具体一点吗?我面前有这本书,但并没有具体说明您可以在哪里或如何称呼他们。
  • 尝试使用调试器单步调试代码,如果您没有调试器,请在代码中添加打印以显示正在发生的事情。
  • 这看起来像是一个家庭作业问题,但我认为您会发现使用调试器逐步执行 rand_int 函数会很有启发性。我会拆分int num = rand() % (range + min); 行,这样您就可以看到那里发生了什么。 (伟大的思想必须以相同的方式思考@brianbeuning)
  • 这已经解释了countless times on SO,但不要使用模运算来限制RNG的输出范围。你会扭曲结果的分布。此外,用time (0) 播种RNG 对您没有任何好处——time (0) 的粒度为1 秒。如果您经常调用rand_int (...),您基本上是在重新播种具有相同值的 RNG。

标签: c++ function random


【解决方案1】:

打开警告可能在这里有所帮助,-Wall 标志 gcc 告诉我们:

warning: the address of 'int rand_int(int, int)' will always evaluate as 'true' [-Waddress]
     cout << rand_int << endl;
             ^

虽然clang 发出警告而不需要添加标志。您在此处使用函数指针,并且由于 std::cout 没有函数指针的 overload,因此它正在选择 bool 重载并将函数指针转换为 true。调用应该是这样的:

std::cout << rand_int(min, max)  <<std::endl;

虽然这不能完全解决您的问题,但您也需要搬家:

srand(time(0));

最好在程序开始时在您的函数之外。由于您以非常快的速度调用 rand_int 十次,因此 time(0) 的结果可能相同,因此您将返回相同的 10 数字。

这一行:

int rand_int(int min, int max);

在for循环中只是对函数的重新声明,不需要。

虽然,如果 C++11 是一个选项,则使用 random header 会更有意义且更简单:

#include <iostream>
#include <random>

int main()
{
    std::random_device rd;

    std::mt19937 e2(rd());

    std::uniform_int_distribution<int> dist(1,10);

    for (int n = 0; n < 10; ++n) {
            std::cout << dist(e2) << ", " ;
    }
    std::cout << std::endl ;
}

如果 C++11 不是一个选项,那么您至少应该查看How can I get random integers in a certain range? C 常见问题解答条目,该条目提供了以下公式,用于在[M, N] 范围内生成数字:

M + rand() / (RAND_MAX / (N - M + 1) + 1)

当然总会有提升:

#include <iostream>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>

int main()
{
  boost::random::mt19937 gen;
  boost::random::uniform_int_distribution<> dist(1, 10);

  for (int n = 0; n < 10; ++n) {
    std::cout << dist(gen) << ", ";
  }
  std::cout << std::endl ;
}

【讨论】:

    【解决方案2】:

    尝试改变这个:

    for(int i = 0; i < 10; i++){
        int rand_int(int min, int max);
        cout << rand_int << endl;
    }
    

    到:

    for(int i = 0; i < 10; i++){
        int myRandomNumber = rand_int(int min, int max);
        cout << myRandomNumber << endl;
    }
    

    看来你是在输出函数而不是函数的返回结果。

    【讨论】:

    • 感谢您的回复,我必须使用 rand 方法,因为它用于分配。我在 for 循环体的第一行不断收到解析错误。 "在 ',' 之前解析错误"
    • @Bobby 好的。专注于我答案的第一部分。我已经删除了不必要的部分。
    【解决方案3】:

    在一个范围内获取随机数的最快和最简单方法是-

    int lower=1,upper=10;//for example
    srand(time(0));
    int y = (rand() % (upper-lower + 1)) + lower;
    

    它将为您提供范围内的输出 - [1,10](均包含)。

    就是这样。干杯!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-27
      • 1970-01-01
      • 2016-05-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多