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

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

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

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

4回答

2144閲覧

c# 数字を重複なしで配列に格納したい

3333566

総合スコア0

C#

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

2グッド

1クリップ

投稿2021/11/11 09:06

編集2021/11/11 09:13

前提・実現したいこと

c# 数字を重複なしで配列に格納したい

発生している問題・エラーメッセージ

エラーメッセージ:無し

該当のソースコード

c#
Random Random = new Random();
int[] number = new int[75];
for (int i = 0; i < number.Length; i++)
{
number[i] = Random.Next(1, 75);
if (!list.Contains(number[i]))
{
list.Add(number[i]);
}
else
{
i--;
}
Console.Out.WriteLine(number[i]);
}

### 試したこと ここに問題に対して試したことを記載してください。 ### 補足情報(FW/ツールのバージョンなど) ここにより詳細な情報を記載してください。
qqfsdfsafd, morimorinoki👍を押しています

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

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

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

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

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

BeatStar

2021/11/11 09:11

とりあえず、"C", "C++" のタグは外しましょう。まったく関係のない言語です。
YAmaGNZ

2021/11/11 10:12

質問は何なのでしょうか?
dodox86

2021/11/11 10:24

確かに、質問というより要望だけ書いてぶん投げですね。 if (!list.Contains(number[i])) んてあるけどlistは未定義だし。コンパイルが通るはずない。
dodox86

2021/11/11 10:34

そもそも質問には「数字を重複無しで」としかないので、乱数でシャッフルする必要もなく、1から75を連番で入れればよいだけでは。
退会済みユーザー

退会済みユーザー

2021/11/12 00:11 編集

「C# シャッフル」でGoogle検索するだけで一件目にやり方出てきますけど、ここに質問書くよりよほど簡単で時間も掛からないと思うのですが、何故出来ないんでしょうね。
guest

回答4

0

例えば乱数の最大値を減らしながら、配列のインデックスを乱数で求めて、空きのインデックスの内の○番目に当たるところを次々埋めていくとか。

投稿2021/11/12 08:02

編集2021/11/12 08:05
qqfsdfsafd

総合スコア599

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

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

K_3578

2021/11/12 08:23

別に低評価はしてないんですけど、回答を分ける必要はあったのでしょうか
qqfsdfsafd

2021/11/12 09:46

手が滑った。 スマホで操作してると時々間違える。というかひとつの質問に同じIDで別の回答が出来る仕様がどうなんだ?
guest

0

この teratail で何度か「現実世界のシミュレーション」という言葉を目にしたので,現実世界でどうやるかなー? と考えてみた結果……

配列をカードに見立てて,カードを混ぜるときと同じようにやれば良いのでは…!? とか思ったので,
「75枚のカードからなるデックを,リフルシャッフルとカットを交互に何度か(下記コードでは5回)行うことで混ぜる」
という形のコードを書いてみました.

CSharp

1class Program 2{ 3 //カット 4 static void Cut_Once( ref int[] Ary, Random rnd ) 5 { 6 int n = Ary.Length; 7 var Result = new int[ n ]; 8 int x = rnd.Next( 0, n ); //カットする場所 9 for( int i=0; i<n; ++i ){ Result[i] = Ary[ (x+i)%n ]; } 10 Ary = Result; 11 } 12 13 //リフルシャッフル 14 static void Shuffle_Once( ref int[] Ary, Random rnd ) 15 { 16 int n = Ary.Length; 17 18 //おおまかに半分に na個 と nb個 に分ける 19 int na = (int)( n * rnd.Next( 40, 60 ) / 100 ); 20 int nb = n - na; 21 22 //2つのグループからちょっとずつResult[]に値をコピーしていく 23 var Result = new int[ n ]; 24 int ia = 0; 25 int ib = na; 26 int iResult = 0; 27 while( iResult<n ) 28 { 29 { 30 int x = Math.Min( rnd.Next( 0, 4 ), na ); 31 for( int i=0; i<x; ++i ) 32 { 33 Result[iResult] = Ary[ ia + i ]; 34 ++iResult; 35 } 36 ia += x; 37 na -= x; 38 } 39 { 40 int x = Math.Min( rnd.Next( 0, 4 ), nb ); 41 for( int i=0; i<x; ++i ) 42 { 43 Result[iResult] = Ary[ ib + i ]; 44 ++iResult; 45 } 46 ib += x; 47 nb -= x; 48 } 49 } 50 Ary = Result; 51 } 52 53 //テスト 54 static void Main () 55 { 56 const int N = 75; 57 //初期状態 58 var Ary = new int[N]; 59 for( int i=0; i<N; ++i )Ary[i]=i; 60 61 {//リフルシャッフルとカットを適当な回数繰り返す 62 Random rnd = new Random(); 63 for( int i=0; i<5; ++i ) 64 { 65 Shuffle_Once( ref Ary, rnd ); 66 Cut_Once( ref Ary, rnd ); 67 } 68 } 69 70 //結果表示 71 for( int i=0; i<N; ++i ) 72 { 73 Console.Write( "{0},", Ary[i].ToString() ); 74 } 75 Console.WriteLine(); 76 } 77}

出力結果例(3回実行してみた分)を以下に示します.

38,54,55,4,63,64,65,24,39,25,66,8,26,16,67,68,17,19,69,56,40,41,34,70,57,58,13,71,46,31,32,42,35,36,51,45,47,14,15,20,74,33,27,21,9,22,48,49,28,29,52,53,5,50,43,0,18,1,6,23,72,73,30,44,7,10,59,60,11,37,2,12,61,62,3, 55,37,5,10,74,67,33,26,66,11,51,47,6,48,9,49,71,38,12,32,72,16,44,45,34,17,3,56,41,39,52,27,28,40,42,57,29,73,53,58,59,18,13,19,68,14,60,20,61,30,0,62,21,63,69,50,31,22,23,24,64,65,1,35,2,36,54,46,25,43,7,8,70,4,15, 19,20,64,9,46,35,73,33,22,65,59,31,23,74,0,1,66,57,3,36,39,32,34,40,21,37,38,47,58,7,26,12,49,43,50,67,13,14,27,5,41,42,51,6,28,29,68,30,15,16,17,60,52,69,48,2,70,56,61,10,71,18,72,11,44,62,24,25,53,54,4,63,55,45,8,

投稿2021/11/12 07:55

編集2021/11/12 08:21
fana

総合スコア11957

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

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

fana

2021/11/12 07:56

in-place な形で書くのが面倒だったので,引数に ref で与えて配列丸ごと取り換えちゃう形になってます.
fana

2021/11/12 08:22 編集

(何回くらいやれば,「ほぼほぼランダム」と言えるのか…? は,わかんないです) リフルで落とす枚数を決めてる乱数の範囲 rnd.Next( 0, 4 ) は,「私だったらこんな感じになるかな…?」っていう,リフルシャッフルの上手さ(下手さ)を表現しています. 出力結果例を追記しました. 値が連続した箇所がちらほら見えるところにリフルの下手さ加減が出ているようにも思えます.
guest

0

2種類書いてみました。お好きなほうをどうぞ。

C#

1using System; 2using System.Linq; 3 4static class Program 5{ 6 static void Main() 7 { 8 WriteData(Figure1(1, 75)); 9 WriteData(Figure2(1, 75)); 10 } 11 12 // 古式ゆかしき 13 static int[] Figure1(int start, int end) 14 { 15 int count = end - start + 1; 16 int[] numbers = new int[count]; 17 for (int i = 0; i < count; i++) 18 { 19 numbers[i] = start + i; 20 } 21 Random random = new Random(); 22 for (int i = 0; i < count - 1; i++) 23 { 24 int j = random.Next(i, count); 25 int temp = numbers[i]; 26 numbers[i] = numbers[j]; 27 numbers[j] = temp; 28 } 29 return numbers; 30 } 31 32 // LinQ 33 static int[] Figure2(int start, int end) 34 { 35 int[] temp = Enumerable.Range(start, end).ToArray(); 36 return temp.OrderBy(a => Guid.NewGuid()).ToArray(); 37 } 38 39 static void WriteData(int[] numbers) 40 { 41 foreach (int number in numbers) 42 { 43 Console.WriteLine($"{number}"); 44 } 45 Console.ReadKey(); 46 } 47}

#追記
なんだかフルボッコで気の毒なので、qqfsdfsafd さんの提案するロジックも書いてみました。
(Figure4/Figure5)
無駄は多いですが、一応、動くようです。
Figure3 は、おそらく質問者さんが実装しようとしてできなかったと思われるロジックです。

C#

1using System; 2using System.Collections.Generic; 3using System.Linq; 4 5partial class Program 6{ 7 // 重複しない値が発生するまで乱数生成を繰り返す 8 static int[] Figure3(int start, int end) 9 { 10 int count = end - start + 1; 11 HashSet<int> numbers = new HashSet<int>(); 12 Random random = new Random(); 13 int max = end + 1; 14 for (int i = 0; i < count; i++) 15 { 16 int number = random.Next(start, max); 17 while (numbers.Contains(number)) 18 { 19 number = random.Next(start, max); 20 } 21 numbers.Add(number); 22 } 23 return numbers.ToArray(); 24 } 25 26 // 二重ループにして重複したらプラス1 27 static int[] Figure4(int start, int end) 28 { 29 int count = end - start + 1; 30 HashSet<int> numbers = new HashSet<int>(); 31 Random random = new Random(); 32 int max = end + 1; 33 for (int i = 0; i < count; i++) 34 { 35 int number = random.Next(start, max); 36 while (numbers.Contains(number)) 37 { 38 number++; 39 } 40 numbers.Add(number); 41 max--; 42 } 43 return numbers.ToArray(); 44 } 45 46 // 空きのインデックスの内の○番目に当たるところを次々埋めていく 47 static int[] Figure5(int start, int end) 48 { 49 int count = end - start + 1; 50 int?[] numbers = new int?[count]; 51 Random random = new Random(); 52 for (int number = start; number <= end; number++) 53 { 54 int index = random.Next(0, count); 55 while (numbers[index].HasValue) 56 { 57 index = random.Next(0, count); 58 } 59 numbers[index] = number; 60 } 61 return (from n in numbers select n.Value).ToArray(); 62 } 63}

投稿2021/11/11 14:33

編集2021/11/12 12:45
KOZ6.0

総合スコア2703

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

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

qqfsdfsafd

2021/11/12 05:14

答えを教えたら考える力が育たない。 低評価。
qqfsdfsafd

2021/11/20 08:40

// 二重ループにして重複したらプラス1の前にこれ入れるの忘れてた。 for (i = 0; i < j; i++) { if (n[j] >= n[i]) { n[j] = n[j] + 1; } }
guest

0

二重ループにして重複したらプラス1すればいいです。

投稿2021/11/11 10:18

qqfsdfsafd

総合スコア599

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

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

qqfsdfsafd

2021/11/11 12:39 編集

>そもそも質問には「数字を重複無しで」としかないので、乱数でシャッフルする必要もなく、1から75を連番で入れればよいだけでは。 何寝ぼけたこと言ってるんだよ。 この質問者は1~75をランダムに並べたいんだよ。 だから1回目は1~75の乱数、2回目は1~74の乱数、3回目は1~73の乱数として二重ループにして重複したらプラス1を繰り返せば解決するんだよ。
Zuishin

2021/11/12 00:42 編集

一回目に 75 が出なければその配列は絶対に完成しない。 重複を数えるのにどれだけの計算量が必要かもわかってない。 プラス 1 の意味がわからない。 何よりただの荒らし。
qqfsdfsafd

2021/11/12 05:13

1回目~74回目までに1~74の数字が埋まるとするじゃん、最後は1が出るじゃん。1は埋まってるからプラス1して2になるじゃん。2も埋まってるからプラス1して3、、、、繰り返せば75になるじゃん。
qqfsdfsafd

2021/11/12 05:18

>「C# シャッフル」 普通はそんな言葉に気付くまで1年掛かる。
Zuishin

2021/11/12 05:21

どんだけ無駄な計算をするつもりなんだか。
kaina

2021/11/12 05:27

シャッフルという言葉を知らなくても質問のタイトルにある「c# 数字 重複なし」という言葉で検索すれば幾らでも参考になるページは見つかりますよ。 ただの怠慢でしょ。
qqfsdfsafd

2021/11/12 06:03

ネット検索してカンニング≒質問してカンニング どっちもどっち、50歩100歩 自分で試行錯誤した。それを元に他人にヒントを貰いたいという思考は怠慢じゃないよ。
fana

2021/11/12 06:13

各回で「まだ出てない値のうち最も小さい値」の採用率が他のまだ出てない値よりも高い形になりそう.
kaina

2021/11/12 06:15

まともな回答を出来ない人にそんなこと言われても。。。 ああ、自分で試行錯誤しようねというのはその通りですね。 ただプログラムを生業としている人でも言語の全てを知って使用しているわけでは無く 必要な情報は本なりネットなりで調べています。 そういった必要な情報を自分で調べる力は必要ですよ。 少なくとも私は質問文から必要な情報を自分で調べようとしたとは読み取れなかったので 怠慢と書きました。 あなたの言う自分で試行錯誤した内容を元に他人にヒントを貰いたいというのは その努力をした後の話しですね。
退会済みユーザー

退会済みユーザー

2021/11/12 06:20 編集

質問の謎の高評価1で自作自演の可能性も濃厚。 どれだけ構ってほしいんだか。
fana

2021/11/12 06:32

> 各回で「まだ出てない値のうち最も小さい値」の採用率が他のまだ出てない値よりも高い形になりそう. いや,これだと言葉がおかしいか. 「まだ出てない値のうち,その手前の値がたくさん既出である値ほど採用率が高くなる」みたいな感じ. とにかく結果が偏りそうに思う. (「既出じゃない値が出るまでサイコロを振り直すぜ!」っていう方法とは,結果が違いそう)
fana

2021/11/12 06:56 編集

且つ,乱数の幅が狭められていくから,各回では大きい値は得られ難くなると思う. 例えば,1回目以外には乱数で 75 を直接出すチャンスは無いので 75 という結果を得るには,少なくとも 現在出せる乱数の最大値 ~ 74  が全て既出である必要がある. (この状態では,乱数が「現在出せる乱数の最大値」のときに,結果値が 75 になる) 多分,この話だと { 1, 75, ... } みたいな結果は絶対に出ないのかな. (1個目が 74 でない限りは,2個目が 75 になることはない) --- そういう話で合っているならば,乱数の幅を狭めることはしなくてもよいのではないでしょうか. 毎回の乱数を常に 1~75 とすれば,少なくとも出ないパターンを無くすことはできるように思います.
qqfsdfsafd

2021/11/12 07:57

そうそう、このように安直に考えると偏りが出る。じゃあ、偏りが出ないようにはどうすればよいか?そういう試行錯誤をする過程が大事なんだよ。
qqfsdfsafd

2021/11/12 07:59

ちなみに高評価したのは俺だけど、質問者は別人です。
qqfsdfsafd

2021/11/12 08:11

こういう質問にコードを書いて教えるのは良くない。
dodox86

2021/11/12 08:15

あなたのこれまでの質問、回答を考えるにまったく意味不明の成り行き。低評価。
qqfsdfsafd

2021/11/12 10:04

それは俺が熟練者だから、俺が知らないものはサンプルソースコードをサクッと手に入れて解決すればよい。 この質問者は初歩の初歩だから自分で試行錯誤する必要がある。
qqfsdfsafd

2021/11/20 08:13

忘れてた。 このロジックの場合、同じ数字だったらプラス1する前に、今までに出た数字以上だったらプラス1するロジックを入れておけば偏りがなくなる。 全部の数字をシャッフルするとかじゃなくて1~75のうち5個の数字を取り出すときなどに使える。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問