嗯,我可能不会这样写,但是:
static IEnumerable<T[]> Permute<T>(this T[] xs, params T[] pre) {
if (xs.Length == 0) yield return pre;
for (int i = 0; i < xs.Length; i++) {
foreach (T[] y in Permute(xs.Take(i).Union(xs.Skip(i+1)).ToArray(), pre.Union(new[] { xs[i] }).ToArray())) {
yield return y;
}
}
}
请回复您的评论;我对这个问题不是完全清楚;如果您的意思是“为什么这有用?” - 除其他外,有一系列蛮力场景,您希望尝试不同的排列 - 例如,对于像旅行销售人员这样的小订单问题(不足以保证更复杂的解决方案),您可能想检查是否最好走 {base,A,B,C,base}, {base,A,C,B,base},{base,B,A,C,base} 等。
如果您的意思是“我将如何使用这种方法?” - 未经测试,但类似:
int[] values = {1,2,3};
foreach(int[] perm in values.Permute()) {
WriteArray(perm);
}
void WriteArray<T>(T[] values) {
StringBuilder sb = new StringBuilder();
foreach(T value in values) {
sb.Append(value).Append(", ");
}
Console.WriteLine(sb);
}
如果您的意思是“它是如何工作的?” - 迭代器块 (yield return) 本身就是一个复杂的主题 - Jon 有一个免费的章节 (6) in his book。其余代码与您最初的问题非常相似 - 只是使用 LINQ 来提供与 + (对于数组)的道德等价物。