前提・実現したいこと
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/ツールのバージョンなど) ここにより詳細な情報を記載してください。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/11 09:19
2021/11/11 10:12
2021/11/11 10:24
2021/11/11 10:34
退会済みユーザー
2021/11/12 00:11 編集
回答4件
0
例えば乱数の最大値を減らしながら、配列のインデックスを乱数で求めて、空きのインデックスの内の○番目に当たるところを次々埋めていくとか。
投稿2021/11/12 08:02
編集2021/11/12 08:05総合スコア599
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/12 08:23
2021/11/12 09:46
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総合スコア11957
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
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総合スコア2703
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/12 05:14
2021/11/20 08:40
0
二重ループにして重複したらプラス1すればいいです。
投稿2021/11/11 10:18
総合スコア599
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/11 12:39 編集
2021/11/12 00:42 編集
2021/11/12 05:13
2021/11/12 05:18
2021/11/12 05:21
2021/11/12 05:27
2021/11/12 06:03
2021/11/12 06:13
2021/11/12 06:15
退会済みユーザー
2021/11/12 06:20 編集
2021/11/12 06:32
2021/11/12 06:56 編集
2021/11/12 07:57
2021/11/12 07:59
2021/11/12 08:11
2021/11/12 08:15
2021/11/12 10:04
2021/11/20 08:13
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。