2013-01-13 3 views
2

저는 C#에 익숙하지 않아 배열로 응용 프로그램을 만들고 있습니다.반복하지 않고 배열 값으로 임의의 숫자를 생성하십시오.

내가해야 할 것은 내가 랜덤 기능을 사용할 때 때문에, 반복하지 않고 배열이 숫자의 순서를 변경입니다
int[] array2 = new int[] { 1, 3, 5, 7, 9 }; 

,이 날 번호를 반복 보여줍니다 나는 아래의 숫자 배열을 가지고있다.

나는이 방법을 보았지만, 숫자를 적용하는 방법을 모른다 : http://www.dotnetperls.com/shuffle

+0

여기서 달성하고자하는 것은 예제 배열에 반복이 없습니까? –

+0

'var array2 = new int [] {1, 3, 5, 7, 9} .OrderBy (_ => rnd.Next())'충분하지 않습니까? – I4V

+1

가능한 모든 주문이 똑같이 * 보장 될 필요가 있습니까? 또한 과거 셔플에서 미래 셔플을 추론 할 수 없다는 보장이 필요합니까 *? (후자의 요구 사항은 우연한 게임에 필수적이며, 현재 데크에서 미래의 데크를 추론 할 수 있다면 온라인 포커가 훨씬 쉽게됩니다.) 두 질문 중 하나에 대한 대답이 "예"이면 여기에 게시 된 답변 중 어느 것도 맞지 않습니다. 작은 편견이나 공격자가 내부 상태를 예측할 수있는 능력에 신경 쓰지 않으면 여기에 게시 된 답변이 합리적입니다. –

답변

5

다음 LINQ 체인 사용할 수 있습니다

int[] array2 = new int[] { 1, 3, 5, 7, 9 }; 
var random = new Random(); 
var total = (int)array2. 
    OrderBy(digit => random.Next()). 
    Select((digit, index) => digit*Math.Pow(10, index)). 
    Sum(); 

첫째, 그 다음, 무작위 요소를 순서를 인덱스의 거듭 제곱으로 10을 곱한 각 요소를 선택한 다음 이들을 합하여 결과를 정수로 변환합니다. 또한 Random 인스턴스에 유용한 시드를 제공하지 않았습니다. 의사 무작위 결과를 내기 위해 그렇게하고 싶을 수도 있습니다.

integer로 캐스트 할 필요가 없도록 here이라고 표시된 지수법 방법을 사용할 수도 있습니다.

편집 : Rhumborl이 지적했듯이, 셔플 된 배열이 필요할 수도 있습니다. 이 경우 :

당신을 위해 일해야합니다.

+0

나는 OP가 여전히 그것의 끝에 배열을 가지고 있다고 생각하는데,이 경우에 단지'var random = new Random(); array2 = array2.OrderBy (n => random.Next()) .ToArray();'할 것이다. – Rhumborl

+0

@Rhumborl 나는 질문의 제목에 대한 나의 대답을 기반으로했지만, 그 내용으로 판단 할 때 진실 일 수 있습니다. 내 게시물을 수정하겠습니다. – Mir

+0

여전히 위대한 게시글입니다. 세부 정보를 유지하십시오. – Rhumborl

0

당신이 말했듯이, 이미 작업 할 숫자가있는 배열이 있습니다. 그래서 고유 번호로 배열을 만드는 방법을 보여주지는 않을 것입니다.

이것은 배열을 임의로 뒤섞는 방법입니다.

  1. 0과 배열의 길이 사이에서 임의의 숫자를 생성하는 방법을 알아보십시오.
  2. 는 다음을 수행 루프 안쪽 length_of_the_array-1 0까지가는 루프 (IDX1으로이 인덱스를 사용)

쓰기 :

을 수행합니다. 1 단계의 방법을 사용하여 0과 idx1 사이의 임의의 숫자를 생성하십시오 (임의의 숫자를 idx2로 지정하십시오).
b. 배열의 요소를 idx1 및 idx2로 바꾸십시오.

간단한 교환이 같은 일을 수행 할 수

TMP = INT의 배열 [IDX1];
배열 [idx1] = 배열 ​​[idx2];
어레이 [idx2] = tmp;

루프가 끝나고 배열이 뒤섞입니다.

+0

downvoter 설명? – Sanchit

+0

설명하는 셔플 알고리즘은 편향을 도입합니다. 잘못된 크 누스 피셔 예이츠 셔플을 묘사하는 가장 일반적인 방법입니다. Jeff는 왜이 알고리즘이 잘못된지에 대한 좋은 분석을 제공합니다. http://www.codinghorror.com/blog/2007/12/shuffling.html –

+0

Roee Gaveril의 대답은 셔플 알고리즘을 올바르게 구현 한 것입니다. –

1

C#으로 작업하는 경우 C# 구조체를 사용하는 것이 좋습니다.

는이 일반적인 기능을

using System; 
using System.Collections.Generic; 

public static class ListExtensions 
{ 
    public static void Shuffle<T>(this IList<T> list) 
    { 
     var randomNumber = new Random(DateTime.Now.Millisecond); 
     var n = list.Count; 
     while (n > 1) 
     { 
      n--; 
      var k = randomNumber.Next(n + 1); 
      var value = list[k]; 
      list[k] = list[n]; 
      list[n] = value; 
     } 
    } 
} 

을 사용할 수 있으며처럼 다음 코드가 보일 것입니다 : 당신은 반복하지 않고 순서를 변경하여 무슨 뜻인지 확실히 모르겠습니다

List<int> list2 = new List<int>(){1, 3, 5, 7, 9}; 
Shuffle(list2); 
+0

크 누스 셔플을 잘 구현했습니다. 필자는 int 배열이 이미 'IList '으로 변환 될 수 있으므로 원하지 않는다면'List '을 사용할 필요가 없다는 것을 알아 두겠습니다. –

+1

그게'list2.Shuffle()'이 아니겠습니까? 확장 메소드를 생성 할 때. – comecme

0

. 당신은 당신이 내 생각은이

private Random rand = new Random(); 
private List<int> used = new List<int>; 
protected int randomNonrepeating() { 
    int i = rand.next(); 
    while(used.contains(i)) 
     i = rand.next(); 
    used.add(i); 
    return i; 
} 

처럼 뭔가를 할 수 반복하지 임의의 숫자를 생성 할 경우에, 그것은 당신이 비록 찾고있는 아주 것이 아니다. 제공된 링크에서 알고리즘을 수정하여 문자열이 아닌 정수 배열로 작업하려는 경우. 유형을 변경하기 만하면됩니다. 이 같은 것이

using System; 

System.Collections.Generic; using System.Linq;

정적 클래스 RandomStringArrayTool { static Random _random = new Random();

public static string[] RandomizeStrings(int[] arr) 
{ 
List<KeyValuePair<int, int>> list = new List<KeyValuePair<int, int>>(); 
// Add all strings from array 
// Add new random int each time 
foreach (var s in arr) 
{ 
    list.Add(new KeyValuePair<int, int>(_random.Next(), s)); 
} 
// Sort the list by the random number 
var sorted = from item in list 
     orderby item.Key 
     select item; 
// Allocate new string array 
int[] result = new string[arr.Length]; 
// Copy values to array 
int index = 0; 
foreach (KeyValuePair<int, int> pair in sorted) 
{ 
    result[index] = pair.Value; 
    index++; 
} 
// Return copied array 
return result; 
} 

}이 도움이

희망.

+0

목록이 크면 첫 번째 알고리즘이 효율적이지 않습니다. 목록에 1000 개의 항목이있는 경우 알고리즘 실행 시간을 계산하는 것이 좋습니다. –

+0

두 번째 알고리즘은 훌륭하지만 필요한 시간보다 약 15 배 더 길게 작성했습니다. 'return (list orderby _random.Next() select item)에서 반환 .ToArray();'잘 할 것이다. –