누구나 가장 효율적인 방식으로 숫자 집합에 대한 모든 순열을 나열하는 C# 코드를 찾을 수있는 링크를 작성하거나 제공 할 수 있습니까? 여기이 얼마나 효율적으로 확실하지만,하지주어진 숫자 집합에 대한 순열을 효율적으로 생성하는 코드 C#
0
A
답변
1
은 몇 가지 옵션이 있습니다 :
+1
이미 해당 링크를 보았습니다. 가장 좋은 해결책이 아닌 것 같습니다. 당신이 알고있는 유용한 링크가 있습니까? –
+1
나를위한 죽은 링크 :( –
0
조금 너무 늦게 ... 그냥 참고로. ..
내 테스트에 따르면, 내 구현 Heap's algorithm의 성능은 내가 본 것 중에서 가장 빠른 성능을 제공하는 것으로 보인다.
장점 :
- 힙의 알고리즘 (순열 당 단일 스왑)
- 없음 곱셈 안전하지 않은 코드
- 일반
- 인라인 된 스왑 (웹에서 본 일부 구현 등)
- 해당 장소에 (매우 낮은 메모리 사용)
- 없음 모듈로하지 Heap's algorithm의
내 구현 (단지 첫 번째 비트는 비교) :
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
namespace WpfPermutations
{
/// <summary>
/// EO: 2016-04-14
/// Generator of all permutations of an array of anything.
/// Base on Heap's Algorithm. See: https://en.wikipedia.org/wiki/Heap%27s_algorithm#cite_note-3
/// </summary>
public static class Permutations
{
/// <summary>
/// Heap's algorithm to find all pmermutations. Non recursive, more efficient.
/// </summary>
/// <param name="items">Items to permute in each possible ways</param>
/// <param name="funcExecuteAndTellIfShouldStop"></param>
/// <returns>Return true if cancelled</returns>
public static bool ForAllPermutation<T>(T[] items, Func<T[], bool> funcExecuteAndTellIfShouldStop)
{
int countOfItem = items.Length;
if (countOfItem <= 1)
{
return funcExecuteAndTellIfShouldStop(items);
}
var indexes = new int[countOfItem];
for (int i = 0; i < countOfItem; i++)
{
indexes[i] = 0;
}
if (funcExecuteAndTellIfShouldStop(items))
{
return true;
}
for (int i = 1; i < countOfItem;)
{
if (indexes[i] < i)
{ // On the web there is an implementation with a multiplication which should be less efficient.
if ((i & 1) == 1) // if (i % 2 == 1) ... more efficient ??? At least the same.
{
Swap(ref items[i], ref items[indexes[i]]);
}
else
{
Swap(ref items[i], ref items[0]);
}
if (funcExecuteAndTellIfShouldStop(items))
{
return true;
}
indexes[i]++;
i = 1;
}
else
{
indexes[i++] = 0;
}
}
return false;
}
/// <summary>
/// This function is to show a linq way but is far less efficient
/// From: StackOverflow user: Pengyang : http://stackoverflow.com/questions/756055/listing-all-permutations-of-a-string-integer
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="length"></param>
/// <returns></returns>
static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> list, int length)
{
if (length == 1) return list.Select(t => new T[] { t });
return GetPermutations(list, length - 1)
.SelectMany(t => list.Where(e => !t.Contains(e)),
(t1, t2) => t1.Concat(new T[] { t2 }));
}
/// <summary>
/// Swap 2 elements of same type
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="a"></param>
/// <param name="b"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
/// <summary>
/// Func to show how to call. It does a little test for an array of 4 items.
/// </summary>
public static void Test()
{
ForAllPermutation("123".ToCharArray(), (vals) =>
{
Console.WriteLine(String.Join("", vals));
return false;
});
int[] values = new int[] { 0, 1, 2, 4 };
Console.WriteLine("Ouellet heap's algorithm implementation");
ForAllPermutation(values, (vals) =>
{
Console.WriteLine(String.Join("", vals));
return false;
});
Console.WriteLine("Linq algorithm");
foreach (var v in GetPermutations(values, values.Length))
{
Console.WriteLine(String.Join("", v));
}
// Performance Heap's against Linq version : huge differences
int count = 0;
values = new int[10];
for (int n = 0; n < values.Length; n++)
{
values[n] = n;
}
Stopwatch stopWatch = new Stopwatch();
ForAllPermutation(values, (vals) =>
{
foreach (var v in vals)
{
count++;
}
return false;
});
stopWatch.Stop();
Console.WriteLine($"Ouellet heap's algorithm implementation {count} items in {stopWatch.ElapsedMilliseconds} millisecs");
count = 0;
stopWatch.Reset();
stopWatch.Start();
foreach (var vals in GetPermutations(values, values.Length))
{
foreach (var v in vals)
{
count++;
}
}
stopWatch.Stop();
Console.WriteLine($"Linq {count} items in {stopWatch.ElapsedMilliseconds} millisecs");
}
}
}
사용 예 : 숫자 주어진의 [순열의
ForAllPermutation("123".ToCharArray(), (vals) =>
{
Console.WriteLine(String.Join("", vals));
return false;
});
int[] values = new int[] { 0, 1, 2, 4 };
ForAllPermutation(values, (vals) =>
{
Console.WriteLine(String.Join("", vals));
return false;
});
0
public static IEnumerable<T[]> Permute<T>(T[] array)
{
for(int i=0; i<array.Length; i++)
{
if (array.Length <= 1)
{
yield return array;
}
else
{
T[] except = new T[array.Length - 1];
Array.Copy(array, except, i);
Array.Copy(array, i + 1, except, i, array.Length - i - 1);
foreach (T[] sub in Permute(except))
{
T[] answer = new T[sub.Length + 1];
Array.Copy(sub, 0, answer, 1, sub.Length);
answer[0] = array[i];
yield return answer;
}
}
}
}
관련 문제
- 1. 주어진 길이의 k의 순열을 찾는 방법은 무엇입니까?
- 2. 비트 시프트는 C의 모든 가능한 순열을 생성하는
- 3. 주어진 단계에서 숫자 시퀀스를 포함하는 벡터를 생성하는 방법은 무엇입니까?
- 4. 문자열의 모든 가능한 순열을 생성하는 C 프로그램의 버그는 어디에 있습니까?
- 5. 주어진 숫자 K와 정렬 된 숫자 세트. 나누는 집합에 숫자가 있는지 찾기
- 6. 순열을 기반으로 키를 생성하는 최적의 알고리즘
- 7. 주어진 정수의 2 자리 숫자
- 8. 주어진 범위에서 숫자 찾기?
- 9. 숫자 만 생성하는 정규식
- 10. 즉석에서 javascript를 생성하는 C# 코드
- 11. 집합에 대한 SQL datetime 근접
- 12. 문자열의 모든 순열을 점진적으로 생성합니다. C#
- 13. 주어진 숫자 다음에 소수 검색하기
- 14. 모든 순열을 사용하여 시퀀스 생성
- 15. 주어진 집합이 집합 집합에 있는지 여부를 쿼리하기위한 데이터 구조
- 16. URL에서 숫자 값을 생성하는 방법
- 17. 주어진 이진 비트의 모든 순열을 찾을 수있는 최상의 알고리즘
- 18. 관계형 데이터베이스 집합에 대한 쿼리
- 19. 두 배열에서 요소의 모든 가능한 순열을 생성합니다.
- 20. 주어진 레코드 ID의 배열을 데이터베이스에서 효율적으로 읽어들입니다.
- 21. 주어진 입력에서 "에코 텍스트"를 생성하는 알고리즘에 대한 아이디어가 필요합니다.
- 22. DataGridview 데이터에서 클래스를 효율적으로 생성하는 방법
- 23. javadocs를 생성하는 자바 코드
- 24. 빈 결과 집합에 대한 NSExpressionDescription
- 25. 데이터 집합에 대한 출력 함수
- 26. 벡터 집합에 대한 상관 행렬
- 27. LINQ 데이터 집합에 대한 쿼리
- 28. 이 파이썬 코드 블록을보다 효율적으로 리팩터링하는 방법
- 29. 주어진 언어/로케일의 임의의 문자열을 생성하는 방법
- 30. C# 알고리즘 - 숫자의 모든 순열을 나열합니다.
가능한 중복 ] (http://stackoverflow.com/questions/1653500/permutations-of-a-given-set-of-numbers) – mafu