質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.30%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

5回答

647閲覧

C# 一次配列に入れた0~9までの10個の配列の数字をランダムに入れ替えたい

turnberry0712

総合スコア4

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

1グッド

0クリップ

投稿2025/06/09 06:25

実現したいこと

一次配列に入れた0~9までの10個の配列の数字をランダムに入れ替えたい

発生している問題・分からないこと

ランダムとはいえ、完全にランダムにできない。ので、どうすれば簡単でありながらランダムに数字を入れ変える事ができるのか、考えているが分からない。

該当のソースコード

C#

1namespace GUNDAM 2{ 3 public class RandomClass //処理を書くためのクラス 4 { 5 public int[] Number10 = new int[10] = {0,1,2,3,4,5,6,7,8,9}; 6 public int[] Replacement = new int[10]; 7 8 public void TestRandomNumberCheckFunction() //配列をランダムする 9 { 10 //謎 11 } 12 } 13}

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q13246726483
特に情報はなかったです。

https://www.isus.jp/security/drng-guide/
こちらは完全ランダムにしようとしておりましたが、ビジュアルスタジオで使えるか分かりませんでした。

補足

特になし

TN8001😄を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cametan

2025/06/09 07:29

うん、多分Shuffleとか呼ばれる関数(あるいはC#だとメソッドか)を書きたい、って質問なんだよな。 そして意外とShuffleの実装は面倒くさい。乱数は独立事象前提なんだけど、Shuffleって従属事象なんだよな(笑)。 => 例えば「くじ引き」がそうで、アルゴリズム的には「配列のランダムな並べ替え」はくじ引きで「無くなるまで引く」に近い コンピュータで従属事象を扱うのって結構メンドイんだ。 だから気の効いた言語処理系だとShuffleとかライブラリとして提供してたりするんだけど・・・・・・C#にはねぇのか。何サボってんだ、Microsoft(笑)。 単純には次のページのように実装すればいいよ、って話じゃない? C# で配列をシャッフルする: https://www.delftstack.com/ja/howto/csharp/shuffle-array-in-csharp/
YAmaGNZ

2025/06/09 07:38

>C#にはねぇのか。 .NET 8から実装されてます。
cametan

2025/06/09 07:54

> .NET 8から実装されてます。 あ、そう。 ならそれ使えば済む話だよね?
YAmaGNZ

2025/06/09 08:07

質問者さんが.NET 8以降を使用しているのか分かりません。 .NET Frameworkなら使えませんし・・・
cametan

2025/06/09 08:09

> 質問者さんが.NET 8以降を使用しているのか分かりません。 あ~、そうなのか~。 結構新しいのかしらん? (ぶっちゃけ、C#は触った事ナシ・笑。F#くらいしか触ったことないからゴメン・笑)
tmp

2025/06/09 08:47

間違ってたらごめんなさい。 Shuffleって擬似乱数つかってるかと、リンクに書いてあるようなセキュリティとかででてくる乱数を使わないと完全とはいえないかもしれない。 最終的な目的を書いてないのでわからないが、「完全ランダム」と、わざわざ書いてるので気になりました。
fana

2025/06/09 09:12

(何らかの方法論が得られたとして,それが「完全にランダム」か否かって,どうやって判断するんだろう?)
cametan

2025/06/09 09:16

所詮疑似乱数になるよねぇ。 C#の乱数の実装法ってどっかに書いてあるのかしらん? メルセンヌ・ツイスタ? どうなんだろ。
cametan

2025/06/09 09:22

ん~。ザーッと検索した限り、.Net 4~5の頃「酷かった」って話は書いてあるけど。 多分.Net 8~9になる(現行?)とMicrosoftのC#実装はマシになってるんじゃないか・・・・・。 いずれにせよ、質問は「もっとマシな疑似乱数生成器を使いたい」って言う意味なのかしらん。
turnberry0712

2025/06/10 04:02

「YAmaGNZ 2025/06/09 15:53 こちらが参考になるかと思います。 https://www.google.com/search?q=C%23+%E9%85%8D%E5%88%97+%E3%82%B7%E3%83%A3%E3%83%83%E3%83%95%E3%83%AB」 拝読いたしました。 「cametan 2025/06/09 16:29 うん、多分Shuffleとか呼ばれる関数(あるいはC#だとメソッドか)を書きたい、って質問なんだよな。 そして意外とShuffleの実装は面倒くさい。乱数は独立事象前提なんだけど、Shuffleって従属事象なんだよな(笑)。 => 例えば「くじ引き」がそうで、アルゴリズム的には「配列のランダムな並べ替え」はくじ引きで「無くなるまで引く」に近い コンピュータで従属事象を扱うのって結構メンドイんだ。 だから気の効いた言語処理系だとShuffleとかライブラリとして提供してたりするんだけど・・・・・・C#にはねぇのか。何サボってんだ、Microsoft(笑)。 単純には次のページのように実装すればいいよ、って話じゃない? C# で配列をシャッフルする: https://www.delftstack.com/ja/howto/csharp/shuffle-array-in-csharp/」 簡単に組むのなら、お二人のようにすれば良いのですね。ありがとうございます。とても参考になります。 「質問者さんが.NET 8以降を使用しているのか分かりません。 .NET Frameworkなら使えませんし・・・」 .NET framework4.8を使用しております。 「tmp 2025/06/09 17:47 間違ってたらごめんなさい。 Shuffleって擬似乱数つかってるかと、リンクに書いてあるようなセキュリティとかででてくる乱数を使わないと完全とはいえないかもしれない。 最終的な目的を書いてないのでわからないが、「完全ランダム」と、わざわざ書いてるので気になりました。」 あまりパソコンに詳しくなく、勉強のためにしております。 その中でランダムな数字を組み込む仕様があり、そのために調べておりました。 「fana 2025/06/09 18:12 (何らかの方法論が得られたとして,それが「完全にランダム」か否かって,どうやって判断するんだろう?)」 疑似ランダムで構いません。よろしくお願いいたします。 「cametan 2025/06/09 18:16 所詮疑似乱数になるよねぇ。 C#の乱数の実装法ってどっかに書いてあるのかしらん? メルセンヌ・ツイスタ? どうなんだろ。」 メルセンヌ・ツイスタのウィキペディア記事を見ました。category:乱数にも目をとおします。人間を対象としてランダムに数がほしいです。PCが同じランダム生成方法を使ってランダムを作られるまでが目的ではありません。
kikukiku

2025/06/11 01:49

解決済みにした場合は下記のどちらかを実施して欲しいです。 結局、どのように解決したのかがわかりません。 1.回答者の中にベストアンサーがあれば、ベストアンサーを付ける。 2.自身で回答を付ける。
fana

2025/06/11 02:24

(この質問は「解決済」って表示されてるけど,どの回答もBAにはなってないように見える.これどういう状況なんだろう? そんなことできるんだっけ?)
TN8001

2025/06/11 04:17

@kikukikuさん > 解決済みにした場合は下記のどちらかを実施して欲しいです。 おそらく質問者さんはBAを押していると思われます。 しかし不具合でうまく反映されなかった。そしてもう出来ることはない状況だと思われます。 [「ベストアンサー」とはどのボタンの事でしょうか](https://teratail.com/questions/672bdqr16qnya5) @fanaさん > (この質問は「解決済」って表示されてるけど,どの回答もBAにはなってないように見える.これどういう状況なんだろう? そんなことできるんだっけ?) はい。以前から稀に見られる現象です。 おそらくteratail側の不具合で、質問者に非はないと思われます。 [コンパイルエラー CS1513](https://teratail.com/questions/4pyhguqlnbx92q)
kikukiku

2025/06/11 05:53

>しかし不具合でうまく反映されなかった。そしてもう出来ることはない状況だと思われます。 そんなことあるんですね。 承知致しました。
guest

回答5

0

以下の通り、一行で済みます。

C#

1//using System.Linq; 2//がソースファイルの一番上に書かれているものとする 3 4//シャッフルする配列 5int[] ary = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 6 7//シャッフルする 8int[] ary2 = ary.OrderBy(i => Guid.NewGuid()).ToArray();

引用元

Guid.NewGuid()が一致するのは天文学的確率でしか起こりえないので、実用的には問題ありません。

投稿2025/06/09 09:22

fiveHundred

総合スコア10402

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cametan

2025/06/09 09:38

これは面白い。
shiketa

2025/06/11 06:00

なるほど~。Javaでも使えるわ。
guest

0

シャッフルは Fisher–Yatesというアルゴリズムがよく使われています。
他の方が紹介している.NET 8のShuffle()や ZLinq.Shuffule()も同じです。
なぜかこのアルゴリズムでのコードの回答が無いので念のため書いておきます。
以下は.NET 8のShuffleのソースコードをint[]用にしただけのものです。

cs

1private Random _random = new Random(); 2 3public void Shuffle(int[] values) 4{ 5 int n = values.Length; 6 for (int i = 0; i < n - 1; i++) 7 { 8 int j = _random.Next(i, n); 9 if (j != i) 10 { 11 int temp = values[i]; 12 values[i] = values[j]; 13 values[j] = temp; 14 } 15 } 16}

投稿2025/06/11 00:22

編集2025/06/11 00:42
hqf00342

総合スコア396

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

turnberry0712

2025/06/12 08:04

回答ありがとうございます。 後ろから(先頭でも構わない)順番に適当な配列と数字を交換できるのですね。 新しい考え方と思えました。 hqf00342さん、ありがとうございます。
guest

0

Cysharp/ZLinqValueEnumerable.Shuffle()を使うと.Net8以前のランタイムでも実用上十分なShuffle()が利用できます。

csharp

1using ZLinq; 2 3int[] randamValues = ValueEnumerable.Range(0, 10).Shuffle().ToArray();

ZLinqのShuffleの実装はこちらで

https://github.com/Cysharp/ZLinq/blob/6d239742f8ba76e54dfea987ca93b02b3be9487c/src/ZLinq/Linq/Shuffle.cs#L7

Randamの生成箇所はこちら

https://github.com/Cysharp/ZLinq/blob/6d239742f8ba76e54dfea987ca93b02b3be9487c/src/ZLinq/Internal/RandomShared.cs#L27

投稿2025/06/09 13:24

tor4kichi

総合スコア773

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

turnberry0712

2025/06/10 04:09

解答ありがとうございます。 見たところ、ZLinqのShuffleの実装の文章で分かりませんでした。 実力が伴わず、大変申し訳ございません。
guest

0

一次配列に入れた0~9までの10個の配列の数字をランダムに入れ替えたい
ランダムとはいえ、完全にランダムにできない。ので、どうすれば簡単でありながらランダムに数字を入れ変える事ができるのか、考えているが分からない。

10個程度に完全も何もないと思うのですが、できうる限り均等にという話なんでしょうか?

ほとんどの場合Randomクラスで十分だと思いますが、入れ替え処理を正しく書くほうが難しいでしょう。
高速で均等なシャッフル手法 ~ 乱数を絞りつくす編 - 屋根裏工房改

.NET Frameworkではいくつかの欠陥がありました。
.NET System.Random の実装と欠陥について ~ 重箱の隅をつつきたおす ~ - 屋根裏工房改

turnberryさんが初心者ということを考えると、.NET8以降を使うようにしていただいてShuffleメソッドを使うのがベストです。
Random.Shuffle メソッド (System) | Microsoft Learn

cs

1int[] values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 2Random.Shared.Shuffle(values);

オーバースペックだと思いますが、暗号レベルのランダム性が欲しければこちらもあります(同.NET8以降)
RandomNumberGenerator.Shuffle<T>(Span<T>) メソッド (System.Security.Cryptography) | Microsoft Learn

cs

1int[] values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 2RandomNumberGenerator.Shuffle(values.AsSpan());

蛇足ですがLINQのShuffleも.NET10 Previewにすでに入っています。
Enumerable.Shuffle<TSource>(IEnumerable<TSource>) Method (System.Linq) | Microsoft Learn

cs

1int[] values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 2values = values.Shuffle().ToArray();

投稿2025/06/09 10:20

編集2025/06/11 13:06
TN8001

総合スコア10091

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

turnberry0712

2025/06/10 04:55

namespace WinFormsApp1 { public partial class Form1 : Form { private void Button1_Click(object sender, EventArgs e) { int[] values = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; Shuffle<int[]>(Span<int[]> values); } } } これであっているでしょうか。おそらくあってないのですが、ここからどうやって使えばいいかわかりませんでした。すみません。
TN8001

2025/06/10 05:41

> これであっているでしょうか。おそらくあってないのですが、ここからどうやって使えばいいかわかりませんでした。すみません。 Randomクラスの場合はこうです。 int[] values = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; Random.Shared.Shuffle(values); RandomNumberGeneratorクラスの場合はこうです。 「using System.Security.Cryptography;」をファイルの頭に追加してください。 int[] values = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; RandomNumberGenerator.Shuffle(values.AsSpan());
turnberry0712

2025/06/10 15:39

Random.Shared.Shuffle(values); Sharedの所でエラーが起きてしまいます。 エラー内容はRandomの所でShared定義がありません。 となってしまいました。 int[] Array = new int[9] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; RandomNumberGenerator.Shuffle(values.AsSpan()); ここはShuffleの部分と.AsSpan()でエラーが発生してしまいました。
TN8001

2025/06/10 16:37 編集

おそらくturnberryさんは、今.NET Frameworkを使っています。 Shuffle等を使うには.NET8以上が必要です。 この辺過去のしがらみやらなんやらでややこしいのですが、簡単に言えば最初に選んだテンプレートが違います。 「Windows フォーム アプリケーション (.NET Framework) 」ではなく、 「Windows フォーム アプリ」を選んでみてください。 .NET 8.0とか.NET 9.0とか選ぶ画面があるはずです。 [Visual Studio を使用して新しいアプリを作成するチュートリアル - Windows Forms | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/desktop/winforms/get-started/create-app-visual-studio)
turnberry0712

2025/06/12 05:59

回答ありがとうございます。 別に作る事になるのですね! 帰宅次第作り直して試して結果を書きます。 再度ありがとうございます。
turnberry0712

2025/06/13 23:46

回答ありがとうございます。 試したところシャッフルが一行でできました! 面白い関数ですね! すごいです!!
TN8001

2025/06/14 05:00

> 試したところシャッフルが一行でできました! よかったです^^ 個人的には.NETのほうを勧めますが(より速くより便利になっている) .NET Frameworkを前提に書いてある本やWebページの通りに行かない場合も多少出てくることがあります。 [C# 13 の新機能 | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-13) [Windows フォームの新機能 - Windows Forms | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/desktop/winforms/whats-new/) [破壊的変更 - .NET Framework から .NET Core | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/core/compatibility/fx-core#windows-forms)
guest

0

多分こうなるんだよな。

C#

1using System; 2using System.Collections.Generic; 3 4class Program 5{ 6 static void Main() 7 { 8 int[] vec = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 9 int[] shuffled = Shuffle(vec); 10 11 Console.WriteLine(string.Join(", ", shuffled)); 12 } 13 14 public static int[] Shuffle(int[] vec) 15 { 16 var list = new List<int>(vec); 17 var acc = new List<int>(); 18 var rand = new Random(); 19 20 while (list.Count > 0) 21 { 22 int index = rand.Next(list.Count); 23 int x = list[index]; 24 list.RemoveAt(index); 25 acc.Add(x); 26 } 27 28 return acc.ToArray(); 29 } 30}

Shuffleの場合、固定長配列じゃ扱いにくい。
よって、一回内部的に可変長のリストへと変換する(List<T>System.Collections.Genericに含まれる)。
乱数(これを出すには、listの現時点での要素数を利用する)で要素番号(index)を選んで、整数xの値を決定する。元リスト(list)からindexの値を削除する。アキュムレータ(acc)にxを追加する。
これを元リスト(list)が空になるまで行う、っつーわけだ。

多分これが一番シンプルなんじゃないかしらん。
識者の意見求む(謎

投稿2025/06/09 09:10

cametan

総合スコア57

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2025/06/09 09:34 編集

> 一番シンプル 配列内でin-placeな形で並べる方が「シンプル」な感じがします.(個人の感想です) 10個の要素のうちのどれを末尾に置くかを乱数できめて,その要素と末尾要素を入れ替える. →これで末尾が決定したので,同様に残りの9個の要素のうち…… っていうやつ.
cametan

2025/06/09 09:36

なる。 ただ、個人的には関数型言語ユーザーなんで(笑)、どうしてもガベコレ頼りで「新しくデータ生成して」返しちゃうんですよねぇ(笑)。 でも確かにOOPの流儀ではないですね。
turnberry0712

2025/06/10 05:03

御返答ありがとうございます。 Varが何を表すかわかりませんでした。 しかし、このまま行うと動いたのでこちらを参考にさせていただきます。 再度、cametanさんありがとうございます。
cametan

2025/06/10 07:50

> Varが何を表すかわかりませんでした。 varは静的型付言語であるC#に於いて、型をコンパイラに「推論」させる為のキーワードです。 暗黙的に型指定されたローカル変数: https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/statements/declarations#implicitly-typed-local-variables 一般に、プログラムを「書く」のは実行時に型が決定する「動的型付け」の方がラクなんだけど、昨今のキレた静的型付け言語だと、C#のvarみたいに「型推論」があって、プログラムを書く側が明示的に型を記述せんでも済む、と言うように進化してきてますね。 なんにせよ、「ラクになることはイイこと」です(笑)。
turnberry0712

2025/06/10 15:06

cametanさん、ありがとうございます。 楽な動的型付け?まだわからないのですが、 記述しなくても、new int  new List<T>みたいに 型を推測してくれるんですね。ありがとうございます。
cametan

2025/06/10 18:16

> 楽な動的型付け?まだわからない プログラミングに於いて、データの「型」ってのは重要なんだけど、大まかにはプログラミング言語は二種類あって、プログラム記述時に明示的にプログラマが型を書いて、例えばコンパイラがコンパイル時に型チェックして「間違いですよ」って教えてくれるのを「静的型付け言語」と言います。C#はこっちね。 一方、プログラマが型を明示せずに、書き上げたプログラムが「実行時」に型を決定するのを「動的型付け言語」と言います。PythonとかRubyとかJavaScriptはこっち。まぁ、極端にいうと、型が原因でバグるかどうかは「走らせてみないと分からない」(笑)。でも一々型宣言せんので、書くのはラクになるかな。 1990年代辺りだとどっちかっつーと動的型付けの方が(開発者側には)人気があって・・・でも2000年代辺りに入ってから(登場はそれ以前なんだけど)、Haskellって言語辺りが「静的型付け」なんだけど「型推論してくれる」って技術を持ち込んできて、それから静的型付けが復権した、っつーか言語開発側に人気が出てきたのね。 そんなカンジです。
fana

2025/06/11 01:38

(さすがに var とかは,「C# var」とかなんとかでググった方が早いのでは)
turnberry0712

2025/06/12 06:01

詳しく教えてくださりありがとうございます。 fanaさんの言う感じ、私の方でも調べてみます。 本当にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問