2016-07-02 38 views
0

所以,我有一個std::list<std::string>,我問,如果有一個函數或把戲隨機列表。隨機化一個std ::列表<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" 

我想你明白我的意思:)

+4

http://en.cppreference.com/w/cpp/algorithm/random_shuffle –

+5

@ πάνταῥεῖ:對'std :: list'不起作用。但是,再次,爲什麼OP使用列表而不是矢量? –

+1

具體來說,'random()'或'random_shuffle()'不適用於不提供隨機訪問迭代器的容器。如前所述,'std :: list'是一個非常不尋常的**容器選擇。幾乎總是。 –

回答

4

如果你要保持你的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.begin(), l.end()); 
    std::random_device rd; 
    std::mt19937 generator(rd()); 
    std::shuffle(v.begin(), v.end(), generator); 
    std::cout << "Original list:\n"; 
    std::copy(l.begin(), l.end(), std::ostream_iterator<std::string>(std::cout, " ")); 
    std::cout << "\nShuffled view:\n"; 
    std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, " ")); 
} 

輸出示例:

Original list: 
Hello Stack Over flow !! 
Shuffled view: 
Hello Over !! Stack flow 

直播例如:https://ideone.com/a1LIyh

0

正如人們所提到的,在這種情況下使用std::list是相當奇怪的 - 真的,你應該使用類似std::vector,將阿爾莫st總是做更好的工作。

儘管如此,對於你的情況,最簡單的「無解」是該列表複製到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來提高效率,但是我會留給你。

+1

請不要使用random_shuffle刪除程序的中間了。它被棄用,將被刪除在C + + 17。改用std :: shuffle。 – MikeMB