random_shuffle和srand()每次都会给我相同的结果
random_shuffle and srand() give me the same result every time
我试图对字母表的随机排列进行一些处理,但尽管使用srand(myseed),每个排列都会产生相同的结果
我已经包含了<algorithm>
标头。
string create_permutation(unsigned seed)
{
srand(seed);
string permutation = ALPHABET;
random_shuffle(permutation.begin(), permutation.end());
return permutation;
}
cout << create_permutation(2) << endl; // or 3, 4, 5 etc
// continuously returns 'XQACKHSLOJ,TRBZNGV.W FIUEYDMP
如有任何帮助,我们将不胜感激。
编辑:最小、完整且可验证的示例
编辑2:对mcve 的调整
#include <iostream>
#include <algorithm>
using namespace std;
const string ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ.,' ";
string create_permutation(unsigned seed)
{
srand(seed);
string permutation = ALPHABET;
random_shuffle(permutation.begin(), permutation.end());
return permutation;
}
int main(){
cout << create_permutation(2) << endl; // or 3, 4, 5 etc
// continuously returns 'XQACKHSLOJ,TRBZNGV.W FIUEYDMP
return 0;
}
问题
- 混洗不是随机的,因为
shuffle_random
每次被调用时都为随机数生成器使用相同的种子
srand
不种子random_shuffle
函数,它种子rand
和random_shuffle
通常调用rand
,但不必。
random_shuffle
有两种形式:
-
一个接受2个参数(开始/结束迭代器)
-
一个需要3(开始/结束迭代器和一个随机生成器)。
您已经证明了您知道如何使用第一种形式,但第一种形式的问题在于,它在不同的平台和编译器中的实现方式不同。它可能根本不使用rand()
,这是srand
种子的函数。
您应该使用3参数形式,并提供随机数生成器作为函数的参数。
您可以按照这个详细的答案来学习如何制作自己的随机数生成器,也可以将rand()
提供给random_shuffle
函数作为随机数生成器。
- 当您为随机数生成器设定种子时,您为将提供伪随机数序列的算法设置起点。如果始终使用相同的种子,则算法将始终具有相同的起点,并且始终生成相同的数字序列
- 每次调用
srand
时,都会重置种子并重置算法的起点。- 这里的一个常见错误是重复调用
srand
。除非你有充分的理由不这样做(如果你这样做了,你可能根本不应该使用rand
和srand。看看<random>
库),否则你应该在程序开始时调用srand
一次,以便在使用该种子后对生成器进行一次种子设定 - CCD_ 18也相当昂贵。从性能的角度来看,您不想经常调用它
- 这里的一个常见错误是重复调用
因此:由于对create_permutation
的每次调用都使用seed
参数调用srand
,并且create_permutation
总是使用相同的种子值调用,因此对于随机数生成器的给定实现,create_permutation
将始终使用相同的随机数序列,从而生成相同的排列。
是一个快速的例子,只要程序运行频率不超过每秒一次,就会生成不同的排列
#include <iostream>
#include <string>
#include <algorithm>
#include <ctime>
const std::string ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ.,' ";
std::string create_permutation()
{
std::string permutation = ALPHABET;
std::random_shuffle(permutation.begin(), permutation.end());
return permutation;
}
int main(){
srand(time(NULL)); // caveat: time's minimum resolution is 1 second.
// multiple executions of this program within 1
// second will get the same time and use the same seed.
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
return 0;
}
一种更现代的方法:
#include <random>
#include <algorithm>
#include <iostream>
#include<string>
const std::string ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ.,' ";
std::random_device rd; // Warning: implementation of this is allowed to be stupid and
// return the same value every time. Does not work in mingw 4.8
// Can't speak for 4.9 or greater
std::mt19937 randomizer(rd());
std::string create_permutation()
{
std::string permutation = ALPHABET;
std::shuffle(permutation.begin(), permutation.end(), randomizer);
return permutation;
}
int main()
{
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
}
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- valgrind-hellgrind与泄漏检查的结果不同
- 用C++20 fmt限制结果的总大小
- 如何返回一个类的两个对象相加的结果
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 序列化,没有库的整数,得到奇怪的结果
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 在更改for循环的第三部分后,未使用for循环结果
- 使用++运算符会导致意外的结果
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- C++Brute Force攻击函数不会返回结果
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 算术运算的结果类似于:C浮点变量中的1/3
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 密码登录程序将永远循环并显示不正确的结果
- 如何让C++'tally up'结果并制定计划?
- 为什么这个程序的结果是3 "born"?和 4 死
- 尝试将字符串/字符转换为整数会产生意外结果