web-dev-qa-db-ja.com

配列からランダムな文字列を選択

配列からランダムな文字列を選択し、同じ文字列を2回選択しないようにするにはどうすればよいですか。

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

これは可能ですか?私は使用することを考えていました

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

ただし、同じ文字列を2回返す可能性があります。それとも私はこれについて間違っていますか?これを達成するためにListのような他のものを使用する必要があります。フィードバックは大歓迎です。

26
atrljoe

最も簡単な方法(ただし、大きなリストの場合は遅い)は、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;

リストが空の場合、すべての値が選択されています。

より高速な方法(特にリストが長い場合)は、リストでシャッフルアルゴリズムを使用することです。その後、値を1つずつポップできます。 Listの末尾から削除するのは、通常、中央から削除するよりもずっと速いため、高速になります。シャッフルについては、詳細について この質問 をご覧ください。

38

以下のこのコードを試してください

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) ] ;
30
Bharat Kumar

最初のステップで配列をシャッフルし、シャッフルされた配列を単純に反復できます。
これには、O(n) O(n ^ 2)と比較してRemoveAtベースの実装にあるという利点があります。もちろん、これは問題ではありません。短い配列の場合。

次の質問に対するJon Skeetの答えをチェックして、良い(すべての順序が同様に可能です)シャッフルの実装を確認してください: RandomとOrderByは良いシャッフルアルゴリズムを使用していますか?

5
CodesInChaos

最善の方法は、重複リストを作成することです。その後、文字列をランダムに選択し、重複リストから削除して、2回選択できないようにします。

2
Icemanind

使用できるロジックは次のとおりです。

1)配列の長さに等しい範囲でランダムな整数を選択します。これを行うには、System.Randomクラスを使用します。

2)その配列インデックスに対応する文字列を使用します

3)配列からそのインデックスを持つアイテムを削除します(リストを使用すると簡単になる場合があります)

その後、もう一度選択すると、同じ文字列は表示されません。配列は1要素短くなります。

2
samb8s
//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;
1
devkiat

元の配列を変更したくない/変更できない場合は、できればListで使用したものを追跡する必要があります。 whileループを使用して、使用されていないことを確認し、「使用済み」リストに追加します。

1
Evan Mulawski

以下のユーティリティメソッドを使用します

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();
1
Siddarth Kanted