以下对随机洗牌的调用始终为向量 v 提供相同的结果
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
using namespace std;
int main(){
vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
srand(time(0));
random_shuffle(v.begin(), v.end());
for (int i = 0; i < v.size(); ++i) printf("%d ", v[i]); printf("\n");
printf("%d\n", rand() % 100);
return 0;
}
我尝试使用
进行编译g++ -std=c++0x
g++ -std=c++11
但是每次都给出相同的结果,所以我不太明白发生了什么。
$./a.out
7 1 4 6 8 9 5 2 3 10
26
$ ./a.out
7 1 4 6 8 9 5 2 3 10
41
$ ./a.out
7 1 4 6 8 9 5 2 3 10
39
OP 的评论清楚地表明这是他们使用的 Clang 和 libc++,而不是 GCC/libstdc++。
random_shuffle
实现 可以看出,它使用 __rs_default
类型的对象作为随机源,检查 __rs_default
的实现表明,它只是使用默认构造的 std::mt19937
对象:
__rs_default::result_type
__rs_default::operator()()
{
static mt19937 __rs_g;
return __rs_g();
}
换句话说,在此实现中,
srand
对random_shuffle
的两参数版本所使用的“随机性”来源没有任何影响。 (可怕的引号,因为它总是使用固定种子。)请注意,根本不需要使用 random_shuffle
,因此您无论如何都不能指望 rand
在可移植代码中“工作”。请使用
srand
和
std::shuffle
设施。<random>
和
-std=c++0x
的意思是完全相同,所以测试两者是没有意义的。 您没有提供完整的程序(请下次阅读https://stackoverflow.com/help/mcve
),所以我猜测了您其余的代码,我尝试了这个:
-std=c++11
我每秒都会得到不同的结果:
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdlib.h>
using namespace std;
int main()
{
vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
srand(time(0));
random_shuffle(v.begin(), v.end());
for (int i : v)
std::cout << i << ' ';
std::cout << std::endl;
}
产生相同结果的次数是因为
tmp$ ./a.out
2 1 8 5 9 7 6 3 10 4
tmp$ ./a.out
10 7 6 3 1 8 9 4 5 2
tmp$ ./a.out
4 7 3 6 5 8 1 9 10 2
tmp$ ./a.out
4 7 3 6 5 8 1 9 10 2
tmp$ ./a.out
4 7 3 6 5 8 1 9 10 2
tmp$ ./a.out
10 2 6 3 9 4 5 7 8 1
tmp$ ./a.out
10 2 6 3 9 4 5 7 8 1
tmp$ ./a.out
10 2 6 3 9 4 5 7 8 1
tmp$ ./a.out
2 1 3 7 5 8 9 6 4 10
返回的秒数相同,因此
time(0)
函数的种子相同,因此结果相同。如果您稍等一下,以便 rand()
返回不同的值,您应该会得到不同的元素随机洗牌。如果您运行的代码与我的不同,您可能会得到不同的结果,但我们不可能解释结果,因为您没有向我们展示您的代码。
标准中不保证
time(0)
将依赖于
std::random_shuffle
。最重要的是:C++14 中已弃用 srand
,C++17 中已删除。从 C++11 开始(问题用
std::random_shuffle
标记),最好使用 c++11
,从 C++20 开始使用
std::shuffle
,并带有显式随机生成器引擎。示例:
std::ranges::shuffle