所以,我有一个std::list<std::string>
,我问是否有一个函数或技巧来随机化列表。
示例:
first elem of the list : "Hello"
second elem of the list : "Stack"
third elem of the list : "Over"
fourth elem of the list : "Flow"
fifth elem of the list : "!!"
我想要的是获取这样的随机列表的函数或技巧,例如:
first elem of the list : "Flow"
second elem of the list : "!!"
third elem of the list : "Hello"
fourth elem of the list : "Stack"
fifth elem of the list : "Over"
我认为你明白我的意思:)。
答案 0 :(得分:5)
如果您希望将list
保留为列表,甚至不修改它,只是提供它的随机“视图”,那么您可以使用vector<reference_wrapper<string>>
然后随机播放该向量。这使列表保持不变,让您在向量中看到它的混乱版本,并且不需要复制所有字符串。
例如:
#include <iostream>
#include <functional>
#include <iterator>
#include <algorithm>
#include <string>
#include <list>
#include <vector>
#include <random>
int main() {
std::list<std::string> l{"Hello", "Stack", "Over", "flow", "!!"};
std::vector<std::reference_wrapper<std::string>> v(l.cbegin(), l.cend());
std::random_device rd;
std::mt19937 generator(rd());
std::shuffle(v.begin(), v.end(), generator);
std::cout << "Original list:\n";
std::copy(l.cbegin(), l.cend(), std::ostream_iterator<std::string>(std::cout, " "));
std::cout << "\nShuffled view:\n";
std::copy(v.cbegin(), v.cend(), std::ostream_iterator<std::string>(std::cout, " "));
}
示例输出:
Original list:
Hello Stack Over flow !!
Shuffled view:
Hello Over !! Stack flow
答案 1 :(得分:0)
正如人们所提到的,在这种情况下使用std::list
是相当奇怪的 - 实际上,你应该使用类似std::vector
的东西,这几乎总能更好地完成同样的工作。
尽管如此,对于您的情况,最简单的非解决方案是&#39;是将列表复制到std::vector
,使用std::random_shuffle
,然后再将其复制回来:
// get some data
std::list<std::string> data = getData();
// copy it into a vector and shuffle it
std::vector<std::string> temp(data.begin(), data.end());
std::random_shuffle(temp.begin(), temp.end());
// copy the (shuffled) vector back into the list
std::copy(temp.begin(), temp.end(), data.begin());
不可否认,由于在两个方向上复制整个数据集,所以效率并不高,但为了您的目的,它应该没问题。如果您愿意,您可以通过移动数据而不是使用std::vector
构造函数和std::copy
来提高效率,但我会将其留给您。