Created
April 10, 2013 08:05
-
-
Save jandk/5352722 to your computer and use it in GitHub Desktop.
Permutes a sequence of a specific type, and lets you enumerate through them
This file contains 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; | |
using System.Collections.Generic; | |
using System.Linq; | |
public class PermuteEnumerator<T> | |
: IEnumerator<IEnumerable<T>> | |
where T : IComparable | |
{ | |
T[] _data; | |
int _length; | |
bool _isReset = true; | |
public PermuteEnumerator(IEnumerable<T> data) | |
{ | |
if (data == null) | |
throw new ArgumentNullException("data"); | |
_data = data.ToArray(); | |
_length = _data.Length; | |
Reset(); | |
Current = _data; | |
} | |
static void Swap(T[] arr, int a, int b) | |
{ | |
T tmp = arr[b]; | |
arr[b] = arr[a]; | |
arr[a] = tmp; | |
} | |
#region IEnumerator<T> Members | |
public IEnumerable<T> Current { get; private set; } | |
public void Dispose() { } | |
object IEnumerator.Current | |
{ | |
get { return Current; } | |
} | |
public bool MoveNext() | |
{ | |
if (_isReset) | |
{ | |
_isReset = false; | |
return true; | |
} | |
// Find the largest i | |
int i = _length - 2; | |
while (i >= 0 && _data[i].CompareTo(_data[i + 1]) > 0) | |
i--; | |
// If i is smaller than 0, then there are no more permutations. | |
if (i < 0) | |
return false; | |
// Find the largest element after vi but not larger than vi | |
int k = _length - 1; | |
while (_data[i].CompareTo(_data[k]) > 0) | |
k--; | |
Swap(_data, i, k); | |
// Swap the last n-i elements | |
k = 0; | |
for (int j = i + 1; j < (_length + i) / 2 + 1; j++, k++) | |
Swap(_data, j, _length - k - 1); | |
return true; | |
} | |
public void Reset() | |
{ | |
Array.Sort(_data); | |
_isReset = true; | |
} | |
#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment