Created
March 4, 2015 09:07
-
-
Save shaybensasson/3de6764d9f83fcaec30f to your computer and use it in GitHub Desktop.
Permutate an array
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Text; | |
| using System.Threading.Tasks; | |
| namespace Assignment2 | |
| { | |
| public static class PermutationExtensions | |
| { | |
| public static bool NextPermutation(this int[] numList) | |
| { | |
| /* | |
| Knuths | |
| 1. Find the largest index j such that a[j] < a[j + 1]. If no such index exists, the permutation is the last permutation. | |
| 2. Find the largest index l such that a[j] < a[l]. Since j + 1 is such an index, l is well defined and satisfies j < l. | |
| 3. Swap a[j] with a[l]. | |
| 4. Reverse the sequence from a[j + 1] up to and including the final element a[n]. | |
| */ | |
| var largestIndex = -1; | |
| for (var i = numList.Length - 2; i >= 0; i--) | |
| { | |
| if (numList[i] < numList[i + 1]) | |
| { | |
| largestIndex = i; | |
| break; | |
| } | |
| } | |
| if (largestIndex < 0) return false; | |
| var largestIndex2 = -1; | |
| for (var i = numList.Length - 1; i >= 0; i--) | |
| { | |
| if (numList[largestIndex] < numList[i]) | |
| { | |
| largestIndex2 = i; | |
| break; | |
| } | |
| } | |
| var tmp = numList[largestIndex]; | |
| numList[largestIndex] = numList[largestIndex2]; | |
| numList[largestIndex2] = tmp; | |
| for (int i = largestIndex + 1, j = numList.Length - 1; i < j; i++, j--) | |
| { | |
| tmp = numList[i]; | |
| numList[i] = numList[j]; | |
| numList[j] = tmp; | |
| } | |
| return true; | |
| } | |
| public static IEnumerable<IEnumerable<T>> QuickPerm<T>(this IEnumerable<T> set) | |
| { | |
| int N = set.Count(); | |
| int[] a = new int[N]; | |
| int[] p = new int[N]; | |
| var yieldRet = new T[N]; | |
| List<T> list = new List<T>(set); | |
| int i, j, tmp; // Upper Index i; Lower Index j | |
| for (i = 0; i < N; i++) | |
| { | |
| // initialize arrays; a[N] can be any type | |
| a[i] = i + 1; // a[i] value is not revealed and can be arbitrary | |
| p[i] = 0; // p[i] == i controls iteration and index boundaries for i | |
| } | |
| yield return list; | |
| //display(a, 0, 0); // remove comment to display array a[] | |
| i = 1; // setup first swap points to be 1 and 0 respectively (i & j) | |
| while (i < N) | |
| { | |
| if (p[i] < i) | |
| { | |
| j = i % 2 * p[i]; // IF i is odd then j = p[i] otherwise j = 0 | |
| tmp = a[j]; // swap(a[j], a[i]) | |
| a[j] = a[i]; | |
| a[i] = tmp; | |
| //MAIN! | |
| for (int x = 0; x < N; x++) | |
| { | |
| yieldRet[x] = list[a[x] - 1]; | |
| } | |
| yield return yieldRet; | |
| //display(a, j, i); // remove comment to display target array a[] | |
| // MAIN! | |
| p[i]++; // increase index "weight" for i by one | |
| i = 1; // reset index i to 1 (assumed) | |
| } | |
| else | |
| { | |
| // otherwise p[i] == i | |
| p[i] = 0; // reset p[i] to zero | |
| i++; // set new index value for i (increase by one) | |
| } // if (p[i] < i) | |
| } // while(i < N) | |
| } | |
| static Random RANDOM = new Random(int.MaxValue); | |
| public static IEnumerable<T> RandomPermutation<T>(this IEnumerable<T> sequence, Random random=null) | |
| { | |
| random = random ?? RANDOM; | |
| T[] retArray = sequence.ToArray(); | |
| for (int i = 0; i < retArray.Length - 1; i += 1) | |
| { | |
| int swapIndex = random.Next(i, retArray.Length); | |
| if (swapIndex != i) | |
| { | |
| T temp = retArray[i]; | |
| retArray[i] = retArray[swapIndex]; | |
| retArray[swapIndex] = temp; | |
| } | |
| } | |
| return retArray; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment