创建所有可能的字符串排列

时间:2014-01-30 14:23:54

标签: c# string selenium

他是我的问题。字符串“Case 1 V1:A,B,C ......”。单词“Case 1 V1:” - 是永久性的,A,B,C - 是变量。 意思是我的String可能包含许多元素,通常是三个元素,有时是4-6个元素。我不知道元素的顺序,意味着一次是“案例1 V1:A,B,C”第二次“案例1 V1:B,A,C”。 我想用所有可能的字符串组合制作List。 有没有简单的方法来创建所有组合?

3 个答案:

答案 0 :(得分: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 :(得分:1)

怎么样:

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个或更多项目的列表,就有成千上万的排列。

正如我上面所说,我认为它会好得多,而不是生成所有选项并逐一测试它们,看看实际上是什么,看它是否符合你的期望。检查列表是否具有预期的项目数,然后检查该列表中的某个位置是否每个预期项目至少出现一次。

答案 2 :(得分:1)

您可以使用典型的排名/排名技术进行排列(实际上,在您的情况下,您只需要 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