글쎄, 아마 내가 그것을 쓸 줄 방법이 아니라 : 귀하의 코멘트를 다시
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를 사용하여 도덕적으로 등가 인 +
(배열의 경우)을 제공하기 만하면됩니다.
튜플이없고 부피가 큰 목록 포함 (예 : LINQ)을 사용하면 C# 코드를 거의 제대로 처리 할 수 있지만 행의 코드를 C#으로 정확하게 변환 할 수 있습니다. – Juliet
이것은 실제로 읽기가 어렵습니다. – hasen