如何处理如下所示的字符串,以便实现所有可能的排列?有这样的努力的LINQ方法吗?我搜索过Google,但找不到任何内容。
STRING = "Little Red Riding Hood"
答案 0 :(得分:2)
This是我过去使用的优秀排列库。这篇文章包含一个代码片段,我认为它可以很好地满足您的需求(我已经略微适应了):
var inputSet = myString.ToCharArray();
var P2 = new Permutations<char>(inputSet,
GenerateOption.WithRepetition);
string format2 = "Permutations of {{A A C}} with Repetition; size = {0}";
Console.WriteLine(String.Format(format2, P2.Count));
foreach(IList<char> p in P2) {
Console.WriteLine(String.Format("{{{0} {1} {2}}}", p[0], p[1], p[2]));
}
答案 1 :(得分:1)
C ++标准模板库(STL)中有一些方法,但我相信这些方法无法从C#中访问(以任何有意义的方式)。我相信你必须为STL写一个小的C ++包装器并从C#调用它;或编码C#中的排列。
更新:
生成N个项目的所有排列是旅行商问题(TSP)的必要前奏。这方面的算法遍布整个网络,这将解释在各种可能的顺序和并行算法 en passant 中生成permutaions。
答案 2 :(得分:1)
您希望使用字符串的字符执行Knuth/Fisher-Yates shuffle。
以下是一堆C#实现,您可以适应字符串而不是数组:Is using Random and OrderBy a good shuffle algorithm?
答案 3 :(得分:1)
这是一个完整的示例程序:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication2
{
internal class Program
{
private static void Main(string[] args)
{
var sentences = new List<string>
{
"Little Red Riding Hood",
"Three Little Pigs",
"Jack and the Beanstalk"
};
foreach (var sentence in sentences)
{
Console.WriteLine("----------------------------------");
foreach (var permutation in Permute(sentence.Split(' ')))
{
foreach (string word in permutation)
{
Console.Write(word + " ");
}
Console.WriteLine();
}
}
// If you want to put all the permutations for all the sentences into a List<string>, you can just do this:
List<string> permutations = new List<string>();
foreach (var sentence in sentences)
{
permutations.AddRange(Permute(sentence.Split(' ')).Select(perm => string.Join(" ", perm)));
}
Console.WriteLine("The total number of perms is: " + permutations.Count);
}
/// <summary>
/// Provides a sequence of enumerators for obtaining all permutations of a sequence.
/// Each enumeration in the returned sequence itself enumerates one of the permutations of the input sequence.
/// Use two nested foreach statements to visit each item in each permuted sequence.
/// </summary>
public static IEnumerable<IEnumerable<T>> Permute<T>(IEnumerable<T> sequence)
{
return permute(sequence, sequence.Count());
}
// Returns an enumeration of enumerators, one for each permutation of the input.
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 concat<T>(new T[] { startingElement }, permutationOfRemainder);
}
++startingElementIndex;
}
}
}
// Implements the recursive part of Permute<T>
private static void permute<T>(T[] items, int item, T[] permutation, bool[] used, Action<T[]> output)
{
for (int i = 0; i < items.Length; ++i)
{
if (!used[i])
{
used[i] = true;
permutation[item] = items[i];
if (item < (items.Length - 1))
{
permute(items, item + 1, permutation, used, output);
}
else
{
output(permutation);
}
used[i] = false;
}
}
}
// Enumerates over all items in the input, skipping over the item with the specified index.
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;
}
}
// Enumerates over contents of two lists sequentially.
private static IEnumerable<T> concat<T>(IEnumerable<T> a, IEnumerable<T> b)
{
foreach (T item in a)
{
yield return item;
}
foreach (T item in b)
{
yield return item;
}
}
}
}