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

I can't figure out what is wrong with this randomizer

本文关键字:发生器 什么 问题 随机 弄清楚      更新时间:2023-10-16

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

我有三个问题。

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

代码:

#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。为什么这个随机生成器会生成非随机数?

您需要为随机数生成器设置种子,以便每次运行时获得不同的结果。否则,(正如您已经注意到的)每次运行都会得到相同的随机数。

把这个放在程序的开头:

srand(time(NULL));

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

注意,您还需要#include <time.h>来访问time()函数。

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

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

srand(time(NULL));

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

如果您不想改变字符串中每个字符的基数(出现的次数),最简单的方法是不逐个选择字符,而是随机选择一对字符进行交换。通过交换,您可以更改顺序,但不能更改基数。

您总是得到相同的随机数,因为您没有播种这个随机数生成器。在第一次呼叫rand()之前先呼叫srand()。示例:http://www.cplusplus.com/reference/clibrary/cstdlib/srand/

rand()生成的随机数为伪随机。c++ rand()文档说明如下

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

这个数字是由一个算法生成的,每次调用它都会返回一个明显不相关的数字序列。该算法使用一个种子来生成序列,该序列应该使用srand初始化为一些不同的值。

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

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

下面的代码记住之前选择的随机数。它只生成一次唯一的随机数。它将结果存储在一个数组中,因此当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 nn";
      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