随机数程序使用函数c++



我创建了一个简单的随机数程序,它接受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;
}

}

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

这是因为:

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';
}

最新更新