我正在尝试生成这些组合:
1
2
3
4
5
12
13
14
15
23
24
25
34
35
45
123
124
125
134
135
145
234
245
345
这是我使用的代码之一,当然不起作用(在上面的例子中 maxValue 是5而 maxCount 是3):
bool nextCombination(int[] combination, int maxValue, int maxCount)
{
if (maxCount < 0)
{
return false;
}
else if (combination[maxCount] < maxValue)
{
combination[maxCount]++;
return true;
}
else
{
return nextCombination(combination, maxValue - 1, maxCount - 1);
}
}
有人可以帮助我吗?
感谢。
答案 0 :(得分:0)
您需要什么组合并不是很清楚。但是如果你想要这个最多3:
1
2
3
12
21
13
31
23
32
123
132
213
231
312
321
您将找到解决方案here。
现在你已经添加了一个完整的例子,我知道你的意思。我添加了一些额外的方法来将上面的列表更改为您想要的内容。
这是您显示结果的方式:
public void ShowRequestedList()
{
var lists = GetRequestedList(Enumerable.Range(1, 5), 3);
foreach (var list in lists)
{
var text = String.Join("", list);
Console.WriteLine(text);
}
}
这是带有额外方法的博客的完整代码。首先是常规方法:
private IEnumerable<IEnumerable<T>> GetRequestedList<T>(IEnumerable<T> items, int maxLenght) where T : IComparable<T>
{
// Next line is explained in the blog
var lists = items.PermutationsWithMissingItems();
// This is what you have to add
return CombinationAreAscending(lists).Where(i => i.Count() <= maxLenght);
}
public IEnumerable<IEnumerable<T>> CombinationAreAscending<T>(IEnumerable<IEnumerable<T>> combinations) where T : IComparable<T>
{
return combinations.Where(CombinationIsAscending);
}
private bool CombinationIsAscending<T>(IEnumerable<T> combination) where T : IComparable<T>
{
var biggest = combination.First();
foreach (var item in combination)
{
if (item.CompareTo(biggest) < 0)
{
return false;
}
biggest = item;
}
return true;
}
public static IEnumerable<int[]> GetCombinations(int length, int maxValue)
{
return
Enumerable.Range(1, maxValue - length)
.Select(first => new { first, firstArray = new[] { first } })
.SelectMany(@t => Enumerable.Range(@t.first + 1, maxValue - @t.first - 2),
(@t, second) => @t.firstArray.Concat(Enumerable.Range(second, length)).ToArray());
}
然后使用扩展方法:
public static class Extensions
{
public static IEnumerable<IEnumerable<T>> Permutations<T>(this IEnumerable<T> source)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
return source.PermutationsImplementation();
}
private static IEnumerable<IEnumerable<T>> PermutationsImplementation<T>(this IEnumerable<T> source)
{
var sourceCache = source.ToList(); // ToList() makes it about twice as fast
if (sourceCache.IsSingle())
{
return sourceCache.ToIEnumerable();
}
return sourceCache
.Select((a, index1) => PermutationsImplementation(sourceCache.Where((b, index2) => index2 != index1))
.Select(b => a.PrependImplementation(b)))
.SelectMany(c => c);
}
public static IEnumerable<TSource> Prepend<TSource>(
this TSource item,
IEnumerable<TSource> items)
{
if (items == null)
{
throw new ArgumentNullException("items");
}
return PrependImplementation(item, items);
}
private static IEnumerable<TSource> PrependImplementation<TSource>(
this TSource item,
IEnumerable<TSource> items)
{
yield return item;
foreach (var item2 in items)
{
yield return item2;
}
}
public static IEnumerable<TSource> ToIEnumerable<TSource>(this TSource item)
{
yield return item;
}
public static bool IsSingle<T>(this IEnumerable<T> source)
{
using (IEnumerator<T> enumerator = source.GetEnumerator())
{
return enumerator.MoveNext() && !enumerator.MoveNext();
}
}
public static IEnumerable<IEnumerable<bool>> AllBooleansCombinations(int count)
{
if (count <= 0)
{
return Enumerable.Empty<IEnumerable<bool>>();
}
if (count == 1)
{
return OneBooleanCombination();
}
var result = AllBooleansCombinations(count - 1).Select(c => false.Prepend(c))
.Concat(
AllBooleansCombinations(count - 1).Select(c => true.Prepend(c)));
return result;
}
private static IEnumerable<IEnumerable<bool>> OneBooleanCombination()
{
yield return false.ToIEnumerable();
yield return true.ToIEnumerable();
}
public static IEnumerable<IEnumerable<T>> WithMissingItems<T>(this IEnumerable<T> source, bool orderItems = true)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
T[] sourceArray = source.ToArray();
var booleansCombinations = AllBooleansCombinations(sourceArray.Length);
var result = booleansCombinations.Select(b => FilterItems(b, sourceArray));
if (orderItems)
{
result = result.Reverse().OrderBy(c => c.Count());
}
return result;
}
private static IEnumerable<T> FilterItems<T>(this IEnumerable<bool> booleans, T[] items)
{
var zippedCombinations = booleans.Zip(items, (boolean, item) => new { boolean, item });
return zippedCombinations.Where(z => z.boolean).Select(z => z.item);
}
public static IEnumerable<IEnumerable<T>> PermutationsWithMissingItems<T>(
this IEnumerable<T> source)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
var withMissingItems = source.WithMissingItems();
return withMissingItems.SelectMany(m => m.Permutations());
}
}