1

私はWindowsアプリに取り組んでいます。このアプリには、フォームに表示される名前の動的リストが含まれています (ユーザーは特定の名前を追加または削除できます)。私がやりたいのは、db の各名前に対して、リストから別のランダムな名前を付けることです。唯一の条件は、名前ごとに異なる名前を割り当て、すべての名前を一度だけ使用する必要があることです。

私がやろうとしたことは、リストを使用してデータベースからの名前を含め、リストからランダムなインデックスを選択して、それをデータベース内の対応する場所と比較することです。異なる場合は、そのインデックスで削除し、配置する名前がなくなるまで繰り返します。

しかし、その後、それは完璧な方法ではないことに気付きました。たとえば、名前が 5 つあるとします。

name 1 はランダムに name 3 を取得します name 2 はランダムに name 1 を取得します name 3 はランダムに name 4 を取得します name 4 はランダムに name 2 を取得します... name 5 は name 5 しか取得できないため、この場合は機能しません。

どうすればそれを機能させることができるか、誰にも分かりますか?他にどのような方法を使用すればよいですか? 名前の数は約 20 です。後で、名前ごとに 2 つの異なる名前を割り当てる必要があります。しかし、まずこの問題を解決する必要があります。

どんな助けでも大歓迎です!C#で書いています

4

5 に答える 5

2

Jan は私を打ち負かしましたが、選択されていない名前が一致した場合に最後の 2 つを切り替える方法を説明するために私が行っていたコードを次に示します。

    static void Main(string[] args)
    {
        List<string> names = new List<string>() { "Jeff", "John", "Joe", "Jack", "Jim" };
        List<string> otherNames = new List<string>() { "Jeff", "John", "Joe", "Jack", "Jim" };

        Random r = new Random();

        for (int i = 4; i >= 0; i--)
        {
            int pick1 = r.Next(i);
            int pick2 = r.Next(i);
            while (names[pick1] == otherNames[pick2])
            {
                pick2++;
                if (pick2 >= otherNames.Count) pick2 = 0;
            }
            if (names.Count == 2)
            {
                // when you only have 2 names left, if the other names match...
                if (names[1 - pick1] == otherNames[1 - pick2])
                {
                    // swap one of the picked names
                    pick2 = 1 - pick2;
                }
            }
            Console.Write(names[pick1]); Console.Write(" != "); Console.WriteLine(otherNames[pick2]);
            names.RemoveAt(pick1);
            otherNames.RemoveAt(pick2);
        }
        Console.ReadKey();
    }
于 2011-06-14T22:01:30.863 に答える
0

List<string> names1つをシャッフルし、コピーを作成し、コピーを1つ下にシフトして(最後のアイテムを最初にする)、位置で名前を一致させる方が簡単だと思います。1回のパスで重複がないことを確認します。

于 2011-06-14T22:10:25.530 に答える
0
while (position == 0) {
   position = randInt() % nameCount;
}

for (int i=0;i<nameCount;i++) {
   addPair(i,position);
   position++;
   if (position>=nameCount) position=0;
}

db 内の名前には、0 から nameCount-1 までの論理番号が付けられます。アイデアは、2 番目の名前のランダムな位置を選択し、それをインクリメントして最後にロールオーバーするというものです。

これは疑似コードです。私はC#を知りません。

素晴らしい質問です。

于 2011-06-14T22:04:01.997 に答える
0

この似たような問題やruby​​ quiz 2の答えを参考にしてみてください。

基本的なアプローチは、リストをコピーし、コピーをシャッフルして、2 つを並べることです。しかし、それはあなたが持っている同じ問題で終わる可能性があります. ただし、自己参照する各リストと交換できるリストに目を通します。

于 2011-06-14T22:05:29.943 に答える