What is the best way to find all combinations of items in an array in c#?
What is the best way to find all combinations of items in an array in c#?
That's called permutations.
This can give you the permutations of any collection:
public class Permutation {
public static IEnumerable<T[]> GetPermutations<T>(T[] items) {
int[] work = new int[items.Length];
for (int i = 0; i < work.Length; i++) {
work[i] = i;
}
foreach (int[] index in GetIntPermutations(work, 0, work.Length)) {
T[] result = new T[index.Length];
for (int i = 0; i < index.Length; i++) result[i] = items[index[i]];
yield return result;
}
}
public static IEnumerable<int[]> GetIntPermutations(int[] index, int offset, int len) {
if (len == 1) {
yield return index;
} else if (len == 2) {
yield return index;
Swap(index, offset, offset + 1);
yield return index;
Swap(index, offset, offset + 1);
} else {
foreach (int[] result in GetIntPermutations(index, offset + 1, len - 1)) {
yield return result;
}
for (int i = 1; i < len; i++) {
Swap(index, offset, offset + i);
foreach (int[] result in GetIntPermutations(index, offset + 1, len - 1)) {
yield return result;
}
Swap(index, offset, offset + i);
}
}
}
private static void Swap(int[] index, int offset1, int offset2) {
int temp = index[offset1];
index[offset1] = index[offset2];
index[offset2] = temp;
}
}
Example:
string[] items = { "one", "two", "three" };
foreach (string[] permutation in Permutation.GetPermutations<string>(items)) {
Console.WriteLine(String.Join(", ", permutation));
}
It is O(n!)
static List<List<int>> comb;
static bool[] used;
static void GetCombinationSample()
{
int[] arr = { 10, 50, 3, 1, 2 };
used = new bool[arr.Length];
used.Fill(false);
comb = new List<List<int>>();
List<int> c = new List<int>();
GetComb(arr, 0, c);
foreach (var item in comb)
{
foreach (var x in item)
{
Console.Write(x + ",");
}
Console.WriteLine("");
}
}
static void GetComb(int[] arr, int colindex, List<int> c)
{
if (colindex >= arr.Length)
{
comb.Add(new List<int>(c));
return;
}
for (int i = 0; i < arr.Length; i++)
{
if (!used[i])
{
used[i] = true;
c.Add(arr[i]);
GetComb(arr, colindex + 1, c);
c.RemoveAt(c.Count - 1);
used[i] = false;
}
}
}
Maybe kwcombinatorics can provide some assistance (see example on home page):
The KwCombinatorics library are 3 classes that provide 3 different ways of generating ordered (ranked) lists of combinations of numbers. These combinatorics are useful for software testing, allowing the generation of various types of possible combinations of input. Other uses include solving mathematical problems and games of chance.
For detailed answer see: Donald Knuth, The Art of computer programming (aka TAOCP). Volume 4A, Enumeration and Backtracking, chapter 7.2. Generating all possibilities. http://www-cs-faculty.stanford.edu/~uno/taocp.html
How about some recursion?
internal HashSet<string> GetAllPermutations(IEnumerable<int> numbers)
{
HashSet<string> results = new HashSet<string>();
if (numbers.Count() > 0)
results.Add(string.Join(",", new SortedSet<int>(numbers)));
for (int i = 0; i <= numbers.Count() - 1; i++)
{
List<int> newNumbers = new List<int>(numbers);
newNumbers.RemoveAt(i);
results.UnionWith(GetAllPermutations(newNumbers));
}
return results;
}
I created a method to get the unique combination of all the integer elements in an array as shown below. I've used Tuple to represent a pair or combination of numbers:
private static void CombinationsOfItemsInAnArray()
{
int[] arr = { 10, 50, 3, 1, 2 }; //unique elements
var numberSet = new HashSet<int>();
var combinationList = new List<Tuple<int, int>>();
foreach (var number in arr)
{
if (!numberSet.Contains(number))
{
//create all tuple combinations for the current number against all the existing number in the number set
foreach (var item in numberSet)
combinationList.Add(new Tuple<int, int>(number, item));
numberSet.Add(number);
}
}
foreach (var item in combinationList)
{
Console.WriteLine("{{{0}}} - {{{1}}}",item.Item1,item.Item2);
}
}
When I invoke this method in a console application then I get below output:
{50} - {10}
{3} - {10}
{3} - {50}
{1} - {10}
{1} - {50}
{1} - {3}
{2} - {10}
{2} - {50}
{2} - {3}
{2} - {1}