2011-07-14 88 views
20

我該如何着手從數組中挑選一個隨機字符串,但不是同時挑選兩個字符串。從數組中挑選隨機字符串

string[] names = { "image1.png", "image2.png", "image3.png", "image4.png", "image5.png" }; 

這可能嗎?我正在考慮使用

return strings[random.Next(strings.Length)]; 

但是,這可能會返回相同的字符串兩次。或者我錯了嗎?我應該使用其他類似List來完成此操作。歡迎任何反饋。

+5

這聽起來像你想* shuffle *數組,然後只是正常迭代數組。 Stack Overflow有很多混洗問題。 –

+1

@Atrljoe - 你明白,返回相同的字符串兩次將是一個隨機的結果嗎?如果你不想兩次得到相同的結果,你想要的結果不能被描述爲隨機結果。 –

+0

@Rhhound當然是隨機的。它不會是一系列*獨立事件,但它仍然是隨機的。 – CodesInChaos

回答

33

最簡單的方法(但對於大型列表來說很慢)將使用List等可調整大小的容器,並在拾取元素後移除元素。如:

var names = new List<string> { "image1.png", "image2.png", "image3.png", "image4.png", "image5.png" }; 

int index = random.Next(names.Count); 
var name = names[index]; 
names.RemoveAt(index); 
return name; 

當您的清單爲空時,所有值都被挑選出來。

更快的方法(尤其是如果您的列表很長)將在您的列表上使用洗牌算法。然後,您可以逐個彈出一個值。這會更快,因爲從List的末尾移除一般比從中間移除要快得多。至於洗牌,你可以看看this question瞭解更多細節。

+1

@ samb8s是的,但我更快:) –

+2

請注意,如果列表很長,這可能是一個壞主意。從長列表開頭附近移除一個項目必須移動它後面的所有項目。 –

+0

@Eric的確,我編輯的時候讓這個更清晰。 –

2

要做的最好的事情就是創建一個重複列表,然後當你隨機挑出一個字符串,你可以從重複列表中刪除它,以便你不能選擇它兩次。

+0

你也打我吧 – samb8s

2

可以使用的邏輯如下:

1)拿起在等於您的陣列的長度的範圍內的隨機整數。您可以使用System.Random類來完成此操作。

2)使用對應於數組索引

3)字符串從數組索引中刪除的項目(可以是一個列表)

然後,你可以再次取相同的字符串更容易將不會出現。數組將會縮短一個元素。

1

如果您不想/不能修改原始數組,您需要跟蹤所使用的數據,最好在List。使用while循環檢查它是否未被使用,然後將其添加到「已使用」列表中。

+4

好吧,假設原始列表中有一千個項目,「已使用」列表中有999個項目。你的計劃是繼續生成隨機數,直到你達到千分之一?你的列表選擇算法會變得越來越慢。對於較長的列表,這是一個糟糕的算法。 –

5

您可以在第一步中對數組進行洗牌,然後簡單地遍歷洗過的數組。
與基於RemoveAt的實現具有的O(n^2)相比,這具有O(n)的優點。當然這對於短陣列來說並不重要。

檢查喬恩斯基特的回答爲好以下問題(所有訂單都同樣可能)實現shuffe的:Is using Random and OrderBy a good shuffle algorithm?

1
//SET LOWERLIMIT 
cmd = new SqlCommand("select min(sysid) as lowerlimit from users", cs); 
int _lowerlimit = (int) cmd.ExecuteScalar(); 
lowerlimit = _lowerlimit; 

//SET UPPERLIMIT 
cmd = new SqlCommand("select max(sysid) as upperlimit from users", cs); 
int _upperlimit = (int) cmd.ExecuteScalar(); 
upperlimit = _upperlimit; 

//GENERATE RANDOM NUMBER FROM LOWERLIMIT TO UPPERLIMIT 
Random rnd = new Random(); 
int randomNumber = rnd.Next(lowerlimit, upperlimit+1); 

//DISPLAY OUTPUT 
txt_output.Text += randomNumber; 
26

嘗試以下

string[] Titles = { "Excellent", "Good", "Super", "REALLY GOOD DOCTOR!", "THANK YOU!", "THE BEST", "EXCELLENT PHYSICIAN", "EXCELLENT DOCTOR" }; 

comments_title.Value=Titles[new Random().Next(0,Titles.Length) ] ; 
+3

將來,請嘗試爲您的帖子添加更多一點說明。好主意,但! :) – davehale23

+0

我一直認爲所有的評論都是誠實的,而不是自動的,那些收到好評的評論其實很好。 – Zurechtweiser

+1

如果它選擇最大值(Titles.Length),這將導致IndexOutOfRangeException。否則,它運作良好。 (只要做標題.Length - 1) – Gober

0

該代碼使用下面的實用方法

public static class ListExtensions 
{ 
    public static T PickRandom<T>(this List<T> enumerable) 
    { 
     int index = new Random().Next(0, enumerable.Count()); 
     return enumerable[index]; 
    } 
} 

然後撥打以下方法

string[] fruitsArray = { "apple", "orange"}; 
string inputString = fruitsArray.ToList().PickRandom();