2013-02-14 4 views
0

반복없이 1-10의 난수로 배열을 채우려고합니다. 나는 재귀로 그것을하려고 노력한다. 나는 재귀와 함께 노력하고있다. (여기에는 두 가지가있다. 어느쪽으로 든 행운이 없다.)반복없이 무작위로 배열 채우기

1 :

static int reco(int arr,int[] times) 
{ 
    Random rnd = new Random(); 
    arr = rnd.Next(1, 11); 
    return times[arr] > 0 ? reco(arr, times) : arr; 
} 

static void Main(string[] args) 
{ 
    int i = 0; 
    int[] arr = new int[10]; 
    int[] times = new int[11]; 
    Random rnd = new Random(); 

    for (i = 0; i < 10; i++) 
    { 
     arr[i] = rnd.Next(1, 11); 
     times[arr[i]]++; 

     if (times[arr[i]] > 0) 
      arr[i] = reco(arr[i], times); 
    } 

2 : I가 작동하지 boths,이 개 코드가

static int reco(int arr,int[] times) 
{ 
    Random rnd = new Random(); 
    arr = rnd.Next(1, 11); 
    if (times[arr] > 0) 
     return reco(arr, times); 
    else 
     return arr; 
} 
static void Main(string[] args) 
{ 
    int i = 0; 
    int[] arr = new int[10]; 
    int[] times = new int[11]; 
    Random rnd = new Random(); 
    for (i = 0; i < 10; i++) 
    { 
     arr[i] = rnd.Next(1, 11); 

     if (times[arr[i]] > 0) 
      arr[i] = reco(arr[i], times); 

     times[arr[i]]++; 
    } 
} 
+0

분석 결과 "작동하지 않음"이라고 설명하십시오. –

+1

배열 0..N에 임의의 순서로 0.N을 채우는 것이 일반적인 경우, 배열을 0.N으로 채우고 배열을 반복하여 각각을 교환하는 것입니다 배열에서 임의의 위치에있는 또 다른 값 - 예 : 셔플. –

답변

0
static void Main() 
    { 
     int[] arr = new int[10]; 
     List<int> numbers = Enumerable.Range(1, 10).ToList(); 
     Random rnd = new Random(); 
     for (int i = 0; i < 10; i++) 
     { 
      int index = rnd.Next(0, numbers.Count - 1); 
      arr[i] = numbers[index]; 
      numbers.RemoveAt(index); 
     } 
    } 
+1

이 솔루션은 작은 배열에서도 작동하지만, 100 만 개 요소를 섞어서 사용하려고하면 어떻게 될지 생각해보십시오. 프로그램을 실행하는 데 얼마나 걸릴까요? –

+0

@EricLippert - 동의하십시오! 거대한 범위의 솔루션은 무엇입니까? –

+1

크 누스 - 피셔 - 예이츠 셔플. –

4

당신은 단지 1과 10 사이의 임의의 숫자를 원하는 경우에, 당신은 할 수 Enumerable.Range을 사용하고 무작위로 주문하십시오.

var ran = new Random(); 
int[] randomArray = Enumerable.Range(1, 10).OrderBy(x => ran.Next()).ToArray(); 
+2

가이드는 임의성의 원인이 아닙니다. 그들은 유일성의 근원입니다. guid 생성기는 순차적 인 guid를 생성 할 수 있습니다. ** 유일성을 위해 GUID를 사용하지 않는다면, 당신은 뭔가 잘못하고있는 것입니다. ** –

+0

@EricLippert, Guid.NewGuid()가 순차적 인 GUIDS 전체를 뱉어내는 것이 이상하다는 것을 알았지 만, 당신의 요점을 봅니다 , 그리고 무작위로 대신 내 대답을 업데이 트했습니다 :) –

+0

새로운 GUID는 당신이 생성 된 GUID가 고유 한 확률이 매우 높다는 것을 보증합니다. (버전 1의 guid도 고유하지 않은 시나리오가 있습니다.) 버전 4 guid는 의사 랜덤이지만 guid 생성기가 버전 4 guid를 생성한다는 보장은 없습니다. 많은 guid 생성기가 순차적으로 버전 1 지침을 생성했습니다. –

2

같은 특정 범위 내의 고유 한 "랜덤"번호 생성 :

List<int> theList = Enumerable.Range(0, 10).ToList(); 
theList.Shuffle(); 

출력 예 :

[1,5,4,8,2,9,6,3,7,0] 

셔플 기능 (출처 : Randomize a List<T>)

public static void Shuffle<T>(this IList<T> list) 
{ 
    Random rng = new Random(); 
    int n = list.Count; 
    while (n > 1) { 
     n--; 
     int k = rng.Next(n + 1); 
     T value = list[k]; 
     list[k] = list[n]; 
     list[n] = value; 
    } 
} 
+2

지금까지는 임의 분포 (임의 분포가 균일 분포를 생성하는 정도까지)와 임의의 크기의 목록에 대해 효율적인 유일한 솔루션입니다. –

+0

난 랜덤의 인스턴스를 통과거야. 'Random'의 기본 생성자는 디자인별로 구분됩니다. – CodesInChaos

0

이렇게 할 수 있습니다. 아래의 코멘트에 에릭 Lippert의 제안한

int[] arr = new int[10]; 

// Fill the array with values 1 to 10: 
for (int i = 0; i < arr.Length; i++) 
{ 
    arr[i] = i + 1; 
} 

// Switch pairs of values for unbiased uniform random distribution: 
Random rnd = new Random(); 
for (int i = 0; i < arr.Length - 1; i++) 
{ 
    int j = rnd.Next(i, arr.Length); 

    int temp = arr[i]; 
    arr[i] = arr[j]; 
    arr[j] = temp; 
} 

이것은 Fisher-Yates (Knuth) shuffle을 사용 문제는 숙제 운동 같은 소리 때문에 재귀 버전은 원래 포스터 운동으로 남아 있습니다.

+0

귀하의 스왑 횟수는 (1) 불필요하게 큽니다. (2) 일정한 분배가 이루어지지 않습니다. 대신 크 누스 셔플 사용을 고려하십시오. –

+0

@EricLippert : 전에이 알고리즘에 대해 들어 본 적이 없어요. 나는 그것이 왜 작동하고 그에 따라 코드를 변경했는지 이해합니다. – Virtlink

1

C#을 사용하고 있으며 배열의 난수를 알고 있기 때문에 배열을 만든 다음 위치를 무작위로 추출하는 것이 어떻습니까? 예를 들면 다음과 같습니다.

using System.Linq; 

//...... 

Random rand = new Random(); 
int[] randomNumbers = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
randomNumbers.OrderBy(num => rand.Next());