随机化std :: list <std :: string>

时间:2016-07-02 03:42:51

标签: c++ list

所以,我有一个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"

我认为你明白我的意思:)。

2 个答案:

答案 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 

实例:https://ideone.com/a1LIyh

答案 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来提高效率,但我会将其留给您。