C# 创建所有可能的字符串排列
他是我的问题。有字符串大小写1 V1:A,B,C。。。。单词case1v1:-是永久的,A、B、C-是变量。 这意味着我的字符串可能包含许多元素,通常是三个,有时是4-6个元素。我不知道元素的顺序,这意味着一次是情况1v1:A,B,C,第二次是情况1v1:B,A,C。 我想列出所有可能的字符串组合。 有没有一种简单的方法来创建所有的组合?我碰巧有一种排列方法,我根据您的需要进行了调整 它输出以下内容,我认为这就是您所要求的:C# 创建所有可能的字符串排列,c#,string,selenium,C#,String,Selenium,他是我的问题。有字符串大小写1 V1:A,B,C。。。。单词case1v1:-是永久的,A、B、C-是变量。 这意味着我的字符串可能包含许多元素,通常是三个,有时是4-6个元素。我不知道元素的顺序,这意味着一次是情况1v1:A,B,C,第二次是情况1v1:B,A,C。 我想列出所有可能的字符串组合。 有没有一种简单的方法来创建所有的组合?我碰巧有一种排列方法,我根据您的需要进行了调整 它输出以下内容,我认为这就是您所要求的: Case 1 V1: A, B, C Case 1 V1: A, C,
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();
}
}
}
那么:
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;
}
}
}
屈服
A, B, C
A, C, B
B, A, C
B, C, A
C, A, B
C, B, A
请注意,它的复杂性为n!其中n是列表中的项目数。因此,三个项目都可以,但一旦你开始进入包含8个或更多项目的列表,就会有成千上万的排列
正如我在上面所说的,我认为最好的办法是查看实际情况,看看是否符合您的预期,而不是生成所有选项并逐个进行测试。检查列表中是否有预期数量的项目,然后检查列表中是否每个预期项目至少出现一次。您可以使用典型的排列/取消排列技术。实际上,在您的情况下,您只需要取消排列:
你试过什么?给我们看一些代码也许你不应该这样做,你应该检查你的网页是否包含三个字母,并且至少包含一个A、至少一个B和至少一个C?看这里:@Plue:这是所有可能的组合,并非所有可能的排列。@Rueven:请注意,您应该使用术语排列而不是组合来描述您的需求。所有的组合将包括空集,A,B,C,A,B,A,C,B等等。我已经更新了我的答案,通过额外调用ToList来强制计算尾部。这使得我的解与马修的解速度相等。大概在我重新计算每个子列表的尾部之前,而不是只做一次工作。
A, B, C
A, C, B
B, A, C
B, C, A
C, A, B
C, B, A
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