我无法弄清楚这个随机发生器有什么问题
I can't figure out what is wrong with this randomizer
我是c++新手。只编程了2天,所以这可能看起来很乱。程序的目的是让你输入一个单词,然后程序随机分配单词中字母的位置。
我有三个问题。
- 为什么,如果输入相同的字符串两次,会输出相同的"随机"数字?
- 我如何确保没有随机数被选中两次。我已经尝试了IF语句嵌套在FOR语句中,但它只是让事情变得更糟。
- 是什么让这个工作?
代码:
#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
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 警告处理为错误这里有什么问题
- 什么时候调用组成单元对象的析构函数
- #定义c-预处理器常量..我做错了什么
- 努力将整数转换为链表。不知道我在这里做错了什么
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 什么时候在C++中返回常量引用是个好主意
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- C++避免重复声明的语法是什么
- c++库的公共头文件中应该包含什么
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- ifstream什么都没读
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 我应该使用什么来代替void作为变体中的替代类型之一
- 我无法弄清楚这个随机发生器有什么问题