如何打乱 std::vector 的顺序?
我正在寻找一种通用的、可重用的方法来在 C++ 中对 std::vector
进行洗牌。这就是我目前的做法,但我认为它不是很有效,因为它需要一个中间数组并且需要知道项目类型(本例中为 DeckCard):
srand(time(NULL));
cards_.clear();
while (temp.size() > 0) {
int idx = rand() % temp.size();
DeckCard* card = temp[idx];
cards_.push_back(card);
temp.erase(temp.begin() + idx);
}
I am looking for a generic, reusable way to shuffle a std::vector
in C++. This is how I currently do it, but I think it's not very efficient because it needs an intermediate array and it needs to know the item type (DeckCard in this example):
srand(time(NULL));
cards_.clear();
while (temp.size() > 0) {
int idx = rand() % temp.size();
DeckCard* card = temp[idx];
cards_.push_back(card);
temp.erase(temp.begin() + idx);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
从 C++20 开始,我们有
C++11 到 C++17,它稍微更详细:
Coliru 上的实时示例
确保在多次调用中重复使用
rng
的相同实例std::shuffle
如果您打算生成每次都有不同的排列!此外,如果您希望程序每次运行时创建不同的洗牌序列,您可以使用
std::random_device
:如果您坚持使用 C++98,您可以使用:
在新代码中避免使用此方法, 尽管:
std::random_shuffle()
在 C++20 中被删除。Since C++20, we have
For C++11 to C++17, it's slightly more verbose:
Live example on Coliru
Make sure to reuse the same instance of
rng
throughout multiple calls tostd::shuffle
if you intend to generate different permutations every time!Moreover, if you want your program to create different sequences of shuffles each time it is run, you can seed the constructor of the random engine with the output of
std::random_device
:If you're stuck with C++98, you may use:
Avoid this for new code, though:
std::random_shuffle()
was removed in C++20.http://www.cplusplus.com/reference/algorithm/shuffle/
请请注意,如果继续对已经洗牌的向量进行洗牌,最终会得到不同的分布。因此,
foo
在循环内定义为具有已知的初始状态。http://www.cplusplus.com/reference/algorithm/shuffle/
Please note the fact that if you keep shuffling a vector already shuffled, you end up with a different distribution. Therefore
foo
is defined inside the loop to have a known initial state.除了 @Cicada 所说的之外,您可能应该先播种,
根据 @FredLarson 的评论:
所以YMMV。
In addition to what @Cicada said, you should probably seed first,
Per @FredLarson's comment:
So YMMV.
甚至可以更简单,可以完全避免播种:
这将在每次运行程序时产生新的洗牌。由于代码简单,我也喜欢这种方法。
这是可行的,因为我们需要
std::shuffle
是一个UniformRandomBitGenerator
,其要求std::random_device
满足。注意:如果重复洗牌,最好将
random_device
存储在局部变量中:It can be even simpler, seeding can be avoided entirely:
This will produce a new shuffle each time the program is run. I also like this approach due to the simplicity of the code.
This works because all we need for
std::shuffle
is aUniformRandomBitGenerator
, whose requirementsstd::random_device
meets.Note: if shuffling repeatedly, it may be better to store the
random_device
in a local variable:如果您使用 boost 您可以使用此类(
debug_mode
设置为false ,如果您希望随机化在执行之间是可预测的,则必须将其设置为< code> true ):
您可以使用以下代码对其进行测试:
If you are using boost you could use this class (
debug_mode
is set tofalse
, if you want that the randomizing could be predictable beetween execution you have to set it totrue
):Than you can test it with this code: