我希望得到数组中所有可能的数字排列 - n!/ k!而n是数组的大小,k是相同数字的数量。
例如,[3,0,0]会有3(3!/ 2!)个可能的排列:
另一个例子是[2,1,0],它会产生6(3!/ 1!)个排列:
我已成功使用here中的代码:
static IEnumerable<IEnumerable<T>>
GetPermutationsWithRept<T>(IEnumerable<T> list, int length)
{
if (length == 1) return list.Select(t => new T[] { t });
return GetPermutationsWithRept(list, length - 1)
.SelectMany(t => list,
(t1, t2) => t1.Concat(new T[] { t2 }));
}
生成排列后,我会运行Sum()
来验证每个排列。然而,这可能不是一种有效的解决方案。还有另一种方法可以达到这个目的吗?
答案 0 :(得分:0)
该函数接受一串字符,并记下该精确字符串的每个可能的排列,例如,如果&#34; ABC&#34;已经提供,应该溢出:
ABC,ACB,BAC,BCA,CAB,CBA。
代码:
enum Type_t
答案 1 :(得分:0)
使用Sum
过滤GetPermutationsWithRept
的输出不正确。考虑这种情况:
{1,2,3}
在这种情况下GetPermutationsWithRept
的一个输出是{2,2}}。总和相等(2 + 2 + 2 = 1 + 2 + 3)。但是,{2,2,2}不是有效输出。
以下是基于您的方法的解决方案:
此类用于比较输出项(计算不同的结果):
public class EnumerableComparer<T> : IEqualityComparer<IEnumerable<T>>
{
public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
{
return x.SequenceEqual(y);
}
public int GetHashCode(IEnumerable<T> obj)
{
return string.Join("-", obj.Select(x => x.ToString())).GetHashCode();
}
}
以下代码调用GetPermutationsWithRept
,并对结果进行两次过滤。第一次删除{3,3,3} ad {2,2,2}等无效项,第二次删除重复项。
var list = new int[] {1, 2, 3};
var result1 = GetPermutationsWithRept(list, 3).ToList();
var sorted_list = list.OrderBy(item => item).ToList();
var result2 = result1
.Where(rlist => rlist.OrderBy(x => x).SequenceEqual(sorted_list)) //first filter
.Distinct(new EnumerableComparer<int>()) //second filter
.ToList();
我认为就性能而言,这种解决方案不适用于大型输入,但它是正确的。