这是我的C#类,用于查找排列或组合:
public static class IEnumerableExtensions
{
public static IEnumerable<IEnumerable<T>> Arrange<T>(this IEnumerable<T> elements,
int places, bool allowRepeats = true, bool orderMatters = true)
{
return orderMatters ?
Permutate(elements, places, allowRepeats) :
Combine(elements, places, allowRepeats);
}
public static IEnumerable<IEnumerable<T>> Permutate<T>(this IEnumerable<T> elements, int places, bool allowRepeats = false)
{
foreach (var cur in elements)
{
if (places == 1) yield return cur.Yield();
else
{
var sub = allowRepeats ? elements : elements.Where(v => !v.Equals(cur));
foreach (var res in sub.Permutate(places - 1, allowRepeats))
{
yield return res.Prepend(cur);
}
}
}
}
public static IEnumerable<IEnumerable<T>> Combine<T>(this IEnumerable<T> elements, int places, bool allowRepeats = false)
{
int i = 0;
foreach (var cur in elements)
{
if (places == 1) yield return cur.Yield();
else
{
var sub = allowRepeats ? elements.Skip(i++) : elements.Skip(i++ + 1);
foreach (var res in sub.Combine(places - 1, allowRepeats))
{
yield return res.Prepend(cur);
}
}
}
}
public static IEnumerable<T> Yield<T>(this T item)
{
yield return item;
}
static IEnumerable<T> Prepend<T>(this IEnumerable<T> rest, T first)
{
yield return first;
foreach (var item in rest)
yield return item;
}
}
使用方法:
var places = new char[] { 'A', 'B', 'C' };
var routes = places.Permutate(3).ToArray();
var noRev = (from r1 in routes
from r2 in routes
where r1.SequenceEqual(r2.Reverse())
select (r1.First() < r2.First() ? r1 : r2)).Distinct();