2011-02-02 4 views
2

문자열의 모든 순열을 증분 방식으로 생성하는 함수를 만들려고합니다. 나는 시작하고 싶습니다 : 나는 주위를 둘러 보았다 있고, 그런 종류의 아무것도 찾을 수 없습니다문자열의 모든 순열을 점진적으로 생성합니다. C#

AAAAA 
... 
AAAAB 
... 
ACCCC 
... 
... 
ZZZZZ 

. 나는 그것을 만들려고했지만 점진적으로되지 않았습니다.

제안 사항?

+2

당신이 점진적으로 무엇을 의미합니까? List에 모든 순열을 추가하는 것을 원하십니까? 아니면 주어진 문자열에서 다음 순열을 생성하는 함수를 원하십니까? – fluminis

+2

이들은 순열이 아닙니다. – btilly

+3

에투, Brute Force. – dotalchemy

답변

1

모듈로 산술을 사용하는 아이디어가있는 다른 변형입니다. 5 글자 Z까지 올라가는 것은 많은 문자열이기 때문에 문자를 {A, B, C}로 낮추어 테스트했습니다.

public IEnumerable<char[]> AlphaCombinations(int length = 5, char startChar = 'A', char endChar = 'C') 
{ 
    int numChars = endChar - startChar + 1; 
    var s = new String(startChar, length).ToCharArray();  
    for (int it = 1; it <= Math.Pow(numChars, length); ++it) 
    {   
     yield return s; 

     for (int ix = 0; ix < s.Length; ++ix) 
      if (ix == 0 || it % Math.Pow(numChars, ix) == 0) 
       s[s.Length - 1 - ix] = (char)(startChar + (s[s.Length - 1 - ix] - startChar + 1) % numChars); 
    } 
} 

... 

foreach (var s in AlphaCombinations(5)) 
{ 
    Console.WriteLine(s); 
} 
+0

이것은 내가 가진 것보다 훨씬 낫습니다! – jjj

0

은 빨리 강타 -이 더 잘 할 수있는 예상 :

public static IEnumerable<string> GenerateStrings(int length = 5) 
{ 
    var buffer = new char[length]; 
    for (int i = 0; i < length; ++i) 
    { 
    buffer[i] = 'A'; 
    } 
    for(;;) 
    { 
    yield return new string(buffer); 

    int cursor = length; 
    for(;;) 
    { 
     --cursor; 
     if (cursor < 0) 
     { 
     yield break; 
     } 

     char c = buffer[cursor]; 
     ++c; 
     if (c <= 'Z') 
     { 
     buffer[cursor] = c; 
     break; 
     } 
     else 
     { 
     buffer[cursor] = 'A'; 
     } 
    } 
    } 
} 
2

는 일반적으로 나는이 무력 유형의 결과를 도움이되지 것입니다 ...하지만 당신이 세트에서 얻을 것이다 얼마나 많은 쓸모없는 결과보고 난 그냥이 던져 거라고 생각.

var query = from c0 in Enumerable.Range(0, 26) 
      from c1 in Enumerable.Range(0, 26) 
      from c2 in Enumerable.Range(0, 26) 
      from c3 in Enumerable.Range(0, 26) 
      from c4 in Enumerable.Range(0, 26) 
      select new string(
       new [] { 
        (char)('A' + c0), 
        (char)('A' + c1), 
        (char)('A' + c2), 
        (char)('A' + c3), 
        (char)('A' + c4), 
       } 
       ); 

BTW ... 그냥 다음 값을 원하는 경우에 당신이 ... 이런 식으로 뭔가를 할 수

public static string Increment(string input) 
{ 
    var array = input.ToCharArray(); 
    if (array.Any(c => c < 'A' || c > 'Z')) 
     throw new InvalidOperationException(); 

    for (var i = array.Length-1; i >= 0; i--) 
    { 
     array[i] = (char)(array[i] + 1); 
     if (array[i] > 'Z') 
     { 
      array[i] = 'A'; 
      if (i == 0) 
       return 'A' + new string(array); 
     } 
     else 
      break; 
    } 
    return new string(array); 
} 
0

여기는 LINQPad 친숙한 코드이며 람다 식을 사용합니다.

void Main() 
{ 
    var chars = Enumerable.Range(65, 26); 

    var strings = chars.SelectMany (a => 
     { 
      return chars.SelectMany (b => chars.SelectMany (c => 
       { 
        return chars.SelectMany (d => 
        { 
         return chars.Select (e => {return new string(new char[] {(char)a, (char)b, (char)c, (char)d, (char)e});}); 
        }); 
       })); 
     }); 

    strings.Dump(); 
} 
4

설명하는 "순열"은 카티 전 곱 (Cartesian product)으로 더 잘 알려져 있습니다. 당신은 당신의 직교 생성물을 형성 할 필요가 시퀀스의 임의의 번호가있는 경우, 주제에이 질문에 대한 내 대답을 참조하십시오

Generating all Possible Combinations

관련 문제