我无法弄清楚这个随机数发生器有什么问题

时间:2011-12-31 02:01:03

标签: c++ random

我是C ++的新手。只编程了2天所以这可能看起来很乱。该程序的目的是输入一个单词,然后程序随机化单词中字母的位置。

我有三个问题。

  1. 为什么,如果两次输入相同的字符串,是否会输出相同的“随机”数字?
  2. 如何确保没有随机数被挑选两次。我已经尝试嵌套在FOR语句中的IF语句,但它只是让事情变得更糟。
  3. 什么能使这项工作?
  4. 代码:

    #include <iostream>
    #include <sstream>
    #include <string>
    #include <cstdlib>
    #include <stdio.h>
    #include <string.h>
    
    using namespace std;
    
    int main () {
        cout << "Enter word to be randomized: ";
        char rstring[30]; 
        char rstring2[30]; 
        cin >> rstring;
        strcpy(rstring2, rstring);
        int length;
        length = strlen(rstring);
    
        int max=length;
        int min=0;
        int randint;
    
        for (int rdm=0; rdm<length; rdm++) {
            randint=rand()%(max-min)+min;
            cout << rstring[rdm]; //This is temporary. Just a visualization of what I'm doing.
            cout << randint << endl; //Temporary as well.
            rstring2[randint]=rstring[rdm];
        }
    
        cout << endl << rstring2 << endl;
        return 0;
    }
    

    如果编译并运行它,您会注意到同一文本输出相同的随机数。像“hello”输出24330.为什么这个随机生成器会产生非随机数?

6 个答案:

答案 0 :(得分:5)

每次运行都需要seed your random number generator才能获得不同的结果。否则,(正如您所注意到的)每次运行都会得到相同的随机数。

将它放在程序的开头:

srand(time(NULL));

这将随机数生成器随时间播种 - 在运行之间可能会有所不同。

请注意,您还需要#include <time.h>才能访问time()功能。

答案 1 :(得分:3)

您没有使用随机数生成器。你正在调用rand(),这是一个伪随机数生成器,它产生的数字序列与真正的随机数共享许多属性(例如,平均值,标准差,频谱都是正确的)。

要获得不同的序列,您必须使用srand()初始化种子。通常的做法是:

srand(time(NULL));

此外,保证相同数字的序列不能被选取两次,不再是i.i.d的序列。 (独立的相同分布)随机数。 (序列高度依赖)随机数的大多数使用依赖于i.i.d.属性,因此库提供的函数是i.i.d.但是,过滤掉自己的重复并不是特别困难。

如果您不想更改字符串中每个字符的基数(出现次数),最简单的方法就是不要选择一个字符,而是随机选择一个字符进行交换。只需交换,即可更改订单,但不能更改基数。

答案 2 :(得分:1)

您总是得到相同的随机数,因为您没有为此随机数生成器设定种子。在第一次致电srand()之前,请致电rand()。示例:http://www.cplusplus.com/reference/clibrary/cstdlib/srand/

答案 3 :(得分:0)

rand()生成的随机数是伪随机数。 C ++ rand()文档说

rand()返回0到RAND_MAX范围内的伪随机整数。

此数字由算法生成,该算法每次调用时都会返回一系列明显不相关的数字。该算法使用种子生成序列,应使用srand将其初始化为某个独特的值。

答案 4 :(得分:0)

因为(至少在Linux上)伪随机数生成器的种子具有相同的值(为了使程序更具确定性,所以连续两次相同的运行将给出相同的答案)。

您可以使用不同的值(时间,pid,等等)为您的PRNG播种。在Linux上,您还可以考虑阅读/dev/urandom(或者很少,甚至是/dev/random)伪文件 - 经常为您的PRNG播种。

答案 5 :(得分:0)

下面的代码会记住以前选择的随机数。 它只生成一次唯一的随机数。 它将结果存储在数组中,以便rand()生成数字时 已经存在,它不会在数组中存储该数字。

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


int main()
{

      int size=100;
      int random_once[100];
      srand(time(0));

      cout<<"generating unique random numbers between [0 and "<<size <<"] only once \n\n";

      for (int i=0;i<size;i++)  // generate  random  numbers 
      {
          random_once[i]=rand() % size;

              //if number already exists, dont store that number in the array
          for(int j=0;j<i;j++) if (random_once[j]==random_once[i]) i--;   
      }

      for ( i=0;i<size;i++) cout<<" "<<random_once[i]<<"\t";
      cout<<"\n";

  return 0;

}

输出:

generating unique random numbers between [0 and 100] only once

 50      80      99      16      11      56      48      36      21      34
 90      87      33      85      96      77      63      5       60      52
 59      4       84      30      7       95      25      1       45      49
 10      43      44      82      22      74      32      68      70      86
 57      24      39      51      83      2       81      71      42      94
 78      72      41      73      92      35      76      9       3       58
 19      40      37      67      31      23      55      69      8       17
 64      46      93      27      28      91      26      65      47      14
 15      75      79      88      62      97      54      12      18      89
 13      38      61      0       29      66      53      6       98      20

Press any key to continue