3

私はスタックオーバーフローが初めてで、vb.net という新しい言語を学んでいます。私はデータベースを使用する必要がある最初のアプリに取り組んでいます。私がやろうとしているのは、列内のすべてのエントリを取得し、それらを配列に入れ、配列をサッフルしてから、新しい配列をデータベースの列。ハットアプリケーションの一種の名前..私は今コードを持っていません.私は最初にレッスンを行っており、多くのフォーラムを検索しています.配列のランダム化、データベース処理などのパズルのピースはすでにたくさんあります.私の問題は、例のシャッフル後にデータが同じ順序になるのを防ぐコードが見つからないことです:

データベースに 4 つのエントリがあるとしましょう: Sarah、james、alex、daniel。

配列をスフリングするとき、どうすればサラが最初に来たり、ジェームズが2番目に来たりするのを防ぐことができますか..

始めるポイントを教えていただければ.. 私がこの言語を学び始めているとあなたに言ったように、私はあなたたちに私のためにアプリを書いてほしくないのですが、ちょっとした手がかりがあるだけでとても感謝しています. オンラインでレッスンをチェックしていますが、初心者コースと「Hello World」の最初のアプリのデモンストレーションに少し飽きてきたので、次のステップの準備ができていると思います!

4

4 に答える 4

0

SQL準拠のデータベースでは、テーブル内の行の物理的な順序はほとんど関係がないと考えられます。これは、テーブルからデータを選択するときに何でも並べ替えることができるためです(SQL Serverの物理的な順序は、クラスター化されたインデックスによって決定/設定されます)。 )。したがって、ソート順をデータベースに保持したい状況では、各行のソートインデックスを格納する列を追加することをお勧めします。

したがって、たとえば、アルファベット順に並べ替えると、データは次のようになります。

Name     SortIndex
------   ---------
Sarah    3
James    2
Alex     0
Daniel   1

また、シャッフルされた場合、物理的な順序は変更されませんが、並べ替えインデックスは次のように変更されます。

Name     SortIndex
------   ---------
Sarah    2
James    0
Alex     1
Daniel   3
于 2012-12-02T12:52:31.773 に答える
0

@Stevenは有効なポイントを獲得しました。SortIndexただし、次のようにクエリで結果を直接シャッフルできるため、を追加せずに実行することもできると思います(バックエンドがMSSQLであると想定)。

SELECT * FROM table1 ORDER BY NEWID()

それでも必要な場合は、プログラムで配列をシャッフルする方法を次に示します。

Dim a() As String = {"Sarah", "James", "Alex", "Daniel"}
Dim shuffledList As New List(Of String)
Randomize()
For i = 0 To UBound(a)
  Dim allowedValues() As String = a.Except(shuffledList).ToArray
  shuffledList.Add(allowedValues(Math.Floor(Rnd() * allowedValues.Count)))
Next

どの要素に対しても元の順序が繰り返されないようにする場合は、代わりに次のコードを使用してください。

Dim a() As String = {"Sarah", "James", "Alex", "Daniel"}
Dim ub As Integer = UBound(a)
Dim shuffledList As New List(Of String)
Randomize()
For i = 0 To ub
  Dim allowedValues() As String = a.Except(shuffledList).Except({a(i)}).ToArray
  Dim randomValue As String
  If i = ub - 1 And allowedValues.Contains(a(ub)) Then
    randomValue = a(ub)
  Else
    randomValue = allowedValues(Math.Floor(Rnd() * allowedValues.Count))
  End If
  shuffledList.Add(randomValue)
Next

ここで最も重要な部分は、最後のアイテムがまだ選択されていない場合に、最後のアイテムの前のアイテムが強制的に最後のアイテムになる場所です。これは、最後のアイテムが最後の位置以外の場所に移動することを確認するためです。そうでない場合、最後のステップで選択するものはありません。全体として、シーケンスはランダムにソートされているように見え、アイテム#1が#1、#2が#2などにならないことが保証されます。アルゴリズムは常にNステップで終了します。ここで、Nはアイテムの数です。

于 2012-12-02T15:08:15.960 に答える
0

最初の例では、最初の順序が無効なシャッフルになるのはなぜですか?

それはさておき、最も簡単な方法は、元のリストを複製し、要素を関数の結果と比較して、そうでなくなるまでランダム化し続けることです。要素リストが 0 または 1 であることを確認することをお勧めします。そうしないと、無限ループが発生します。

于 2012-12-02T07:02:57.850 に答える
0

回答ありがとうございます。私はすでにそのスクリプトを別の言語で作成しました。それを実現する方法は非常に簡単です。

同じ配列を取る: Sarah、James、Alex、Daniel;

配列を複製します。

次に、最初の配列のすべてのエントリが、2 番目の配列のランダムなエントリを選択します。サラが最初に行くだろう - 彼女が自分の名前を選ぶなら、それをキャンセルして、彼女が別の名前を選ぶまでもう一度選ぶ;

次に、選択した名前を 2 番目の配列から削除します。

次に、2 番目の名前、3 番目の名前ですべての手順を繰り返します...

もちろん、これはすべてループによって行われます。

たぶん、これはすべてvb.netで非常に簡単に達成できますが、vb.netには「Ramdomize.PreventSameSortIndexOrder」のような関数がないことを(あまり知らなくても)確信しています;)。スティーブンがデモンストレーションしていたことは理解できますが、このようにして、suffle の後でインデックス ID が同じ場所に戻らないようにする方法を説明していただけますか? 私はVBでMS Accessデータベースを扱うことを学んでいましたが、何らかの理由でSQLの方が優れている場合は、切り替えても問題ありません。@Neoliskあなたが書いたこのコマンドについて詳しく教えてください:

SELECT * FROM table1 ORDER BY NEWID()

皆さんありがとう!

于 2012-12-02T17:16:53.837 に答える