2014-01-30 74 views
-1

他是我的問題。有字符串「案例1 V1:A,B,C ...」。單詞「案例1 V1:」是永久性的,A,B,C是變量。 含義我的字符串可能包含許多元素,通常是三個,有時是4-6個元素。我不知道元素的順序,一次是「案例1 V1:A,B,C」,第二次「案例1 V1:B,A,C」。 我想列出所有可能的字符串組合。 是否有創建所有組合的簡單方法?創建所有可能的字符串排列

+1

Whay你試過嗎?告訴我們一些代碼 – Peter

+0

也許你不應該這樣做,你應該檢查你的網頁是否只包含三個字母,並且包含至少一個A,至少一個B和至少一個C? –

+0

看這裏:http://stackoverflow.com/questions/7802822/all-possible-combinations-of-a-list-of-values-in-c-sharp – Plue

回答

0

如何:

public static IEnumerable<IEnumerable<T>> Permutations<T>(IEnumerable<T> items) 
{ 
    foreach (var item in items) 
    { 
     var head = new T[] { item }; 
     var tail = items.Except(head).ToList(); 
     var subLists = Permutations(tail); 
     if (subLists.Any()) 
     { 
      foreach (var subList in subLists) 
      { 
       yield return head.Concat(subList); 
      } 
     } 
     else 
     { 
      yield return head; 
     } 
    } 
} 

以下

foreach (var p in Permutations(new string[] { "A", "B", "C" })) 
{ 
    Console.WriteLine(string.Join(", ", p)); 
} 

產量

A, B, C 
A, C, B 
B, A, C 
B, C, A 
C, A, B 
C, B, A 

注意,這有複雜的n階!其中n是列表中的項目數量。所以它對三件物品很好,但是一旦你開始進入8件或更多物品的列表中,就會有成千上萬的組合。

正如我上面所說,我認爲這會好得多,而不是生成所有選項並逐一測試它們,看看實際存在的內容,看看它是否與您期望的相符。檢查列表是否具有預期的項目數量,然後檢查該列表中某個預期項目是否至少出現一次。

+0

我還沒有設法圍繞他的代碼如何工作,但在測試中,我只用362,880排列運行,德米特里顯着更快 - 大約1秒到16秒。我猜,我所有的遞歸編程都沒有針對它進行優化。 –

+0

馬修的同樣的測試需要大約2秒,仍然明顯快於我的方法 –

+0

我已經更新了我的答案,以強制計算尾部的額外呼叫ToList。這使我的解決方案與Matthew的解決方案具有同等的速度。大概在我重新計算每個子列表的尾部之前,而不是隻做一次工作。 –

1

我碰巧有一個Permute方法躺在我周圍適應您的需求。

它輸出下面,我想這是你問什麼:

Case 1 V1: A, B, C 
Case 1 V1: A, C, B 
Case 1 V1: B, A, C 
Case 1 V1: B, C, A 
Case 1 V1: C, A, B 
Case 1 V1: C, B, A 

下面的代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace Demo 
{ 
    internal class Program 
    { 
     private void run() 
     { 
      string prefix = "Case 1 V1: "; 
      string[] possibilities = {"A", "B", "C"}; 

      foreach (var permutation in Permute(possibilities)) 
       Console.WriteLine(prefix + string.Join(", ", permutation)); 
     } 

     public static IEnumerable<IEnumerable<T>> Permute<T>(IEnumerable<T> sequence) 
     { 
      return permute(sequence, sequence.Count()); 
     } 

     private static IEnumerable<IEnumerable<T>> permute<T>(IEnumerable<T> sequence, int count) 
     { 
      if (count == 0) 
      { 
       yield return new T[0]; 
      } 
      else 
      { 
       int startingElementIndex = 0; 

       foreach (T startingElement in sequence) 
       { 
        IEnumerable<T> remainingItems = allExcept(sequence, startingElementIndex); 

        foreach (IEnumerable<T> permutationOfRemainder in permute(remainingItems, count - 1)) 
         yield return (new [] { startingElement }).Concat(permutationOfRemainder); 

        ++startingElementIndex; 
       } 
      } 
     } 

     private static IEnumerable<T> allExcept<T>(IEnumerable<T> input, int indexToSkip) 
     { 
      int index = 0; 

      foreach (T item in input) 
      { 
       if (index != indexToSkip) 
        yield return item; 

       ++index; 
      } 
     } 

     private static void Main() 
     { 
      new Program().run(); 
     } 
    } 
} 
1

您可以使用典型的等級/ unrank方式來給排列(實際上,你的情況,你想unrank只):

public static class Permutations { 
    public static BigInteger Count(int size) { 
     if (size < 0) 
     return 0; 

     BigInteger result = 1; 

     for (int i = 2; i <= size; ++i) 
     result *= i; 

     return result; 
    } 

    public static int[] Unrank(int size, BigInteger rank) { 
     if (size < 0) 
     throw new ArgumentOutOfRangeException("size", "size should not be negative."); 
     else if (rank < 0) 
     throw new ArgumentOutOfRangeException("rank", "size should not be negative."); 

     int[] digits = new int[size]; 

     for (int digit = 2; digit <= size; ++digit) { 
     BigInteger divisor = digit; 

     digits[size - digit] = (int) (rank % divisor); 

     if (digit < size) 
      rank /= divisor; 
     } 

     int[] permutation = new int[size]; 
     List<int> usedDigits = new List<int>(size); 

     for (int i = 0; i < size; ++i) 
     usedDigits.Add(0); 

     for (int i = 0; i < size; ++i) { 
     int v = usedDigits.IndexOf(0, 0); 

     for (int k = 0; k < digits[i]; ++k) 
      v = usedDigits.IndexOf(0, v + 1); 

     permutation[i] = v; 
     usedDigits[v] = 1; 
     } 

     return permutation; 
    } 
    } 

    ... 

     StringBuilder Sb = new StringBuilder(); 

     String data = "Case 1 V1: A, B, C"; 

     String[] items = data.Substring("Case 1 V1:".Length).Trim().Split(',').Select(x => x.Trim()).ToArray(); 

     for (int i = 0; i < (int) Permutations.Count(items.Length); ++i) { 
     if (Sb.Length > 0) 
      Sb.AppendLine(); 

     Sb.Append("Case 1 V1: "); 

     Boolean firstItem = true; 

     foreach (int j in Permutations.Unrank(items.Length, i)) { 
      if (!firstItem) 
      Sb.Append(", "); 

      firstItem = false; 

      Sb.Append(items[j]); 
     } 
     } 

     String result = Sb.ToString(); 

輸出

Case 1 V1: A, B, C 
Case 1 V1: A, C, B 
Case 1 V1: B, A, C 
Case 1 V1: B, C, A 
Case 1 V1: C, A, B 
Case 1 V1: C, B, A 
相關問題