patterncsharpMinor
Generating permutations and combinations
Viewed 0 times
andgeneratingcombinationspermutations
Problem
How can this code be improved?
```
using System;
//using System.Linq;
using System.Collections;
using System.Collections.Generic;
namespace Combinatorics
{
public class Permutation
{
private int[] data = null;
private int order = 0;
public Permutation(int n)
{
this.data = new int[n];
for (int i = 0; i = 0; --i)
{
this.data[i] = temp[i];
for (int j = i + 1; j = this.data[i])
++this.data[j];
}
}
for (int i = 0; i result.data[left + 1]) && (left >= 1))
{
--left;
}
if ((left == 0) && (this.data[left] > this.data[left + 1]))
return null;
right = result.order - 1; // Step #2 - find right; first value > left
while (result.data[left] > result.data[right])
{
--right;
}
int temp = result.data[left]; // Step #3 - swap [left] and [right]
result.data[left] = result.data[right];
result.data[right] = temp;
int i = left + 1; // Step #4 - order the tail
int j = result.order - 1;
while (i tempList = new List(data);
for (int i = 0; i this.n - 1)
return false; // value out of range
for (int j = i + 1; j = this.data[j])
return false; // duplicate or not lexicographic
}
return true;
} // IsValid()
public Combination Next()
{
if (this.data[0] == this.n - this.k)
return null;
Combination ans = new Combination(this.n, this.k);
int i;
for (i = 0; i 0 && ans.data[i] == this.n - this.k + i; --i)
;
++ans.data[i];
for (int j = i; j x)
--v;
return v;
} // LargestV()
public static ArrayList Generate(Object[] list, int choose, bool random)
{
Combination c = new Combination(list.Length, choose);
ArrayList result = new
```
using System;
//using System.Linq;
using System.Collections;
using System.Collections.Generic;
namespace Combinatorics
{
public class Permutation
{
private int[] data = null;
private int order = 0;
public Permutation(int n)
{
this.data = new int[n];
for (int i = 0; i = 0; --i)
{
this.data[i] = temp[i];
for (int j = i + 1; j = this.data[i])
++this.data[j];
}
}
for (int i = 0; i result.data[left + 1]) && (left >= 1))
{
--left;
}
if ((left == 0) && (this.data[left] > this.data[left + 1]))
return null;
right = result.order - 1; // Step #2 - find right; first value > left
while (result.data[left] > result.data[right])
{
--right;
}
int temp = result.data[left]; // Step #3 - swap [left] and [right]
result.data[left] = result.data[right];
result.data[right] = temp;
int i = left + 1; // Step #4 - order the tail
int j = result.order - 1;
while (i tempList = new List(data);
for (int i = 0; i this.n - 1)
return false; // value out of range
for (int j = i + 1; j = this.data[j])
return false; // duplicate or not lexicographic
}
return true;
} // IsValid()
public Combination Next()
{
if (this.data[0] == this.n - this.k)
return null;
Combination ans = new Combination(this.n, this.k);
int i;
for (i = 0; i 0 && ans.data[i] == this.n - this.k + i; --i)
;
++ans.data[i];
for (int j = i; j x)
--v;
return v;
} // LargestV()
public static ArrayList Generate(Object[] list, int choose, bool random)
{
Combination c = new Combination(list.Length, choose);
ArrayList result = new
Solution
-
Why have you commented out
It can be replaced with:
-
In first two
Effectively,
-
In the
-
In many places, it is unclear what's going on and how to use these classes. Add some documentation. I would never guess how
-
This statement in the second
I would remove
Also consider using LINQ here and replace it with:
I wasn't strong enough to read through second class, so probably some my points will be applicable there also.
Why have you commented out
Linq namespace? Use it at least here:this.data = new int[n];
for (int i = 0; i < n; ++i)
{
this.data[i] = i;
}It can be replaced with:
this.data = Enumerable.Range(0, n).ToArray();-
In first two
Permutation constructors you have:public Permutation(int n)
{
this.data = new int[n];
...
this.order = n;
}
public Permutation(int n, int k)
{
this.data = new int[n];
this.order = this.data.Length;
...
}Effectively,
order is being set to the same value, but you're doing it in a different way in similar scenarios. This makes it more confusing. Either use order = n in both places or use order = data.Length. Keep it consistent.-
In the
Permutation class, you have field order which is always set to be a length of data and you also have a property to retrieve this field. I believe this additional field makes this code more error prone because you have to remember to set this field. I would remove it and replace Order property to return data.Length.-
In many places, it is unclear what's going on and how to use these classes. Add some documentation. I would never guess how
Permutation.Element(n) would return new Permutation.-
This statement in the second
Permutation constructor is misleading: for (int i = 0; i < n; ++i)
{
temp[i] = ++factoradic[i]; // <-- Why ++ ???
}I would remove
++ here. In this way it makes me think that factoradic[i] is used somewhere else, but it is not. Use factoradic[i] + 1 instead. Remember that when somebody will read/review your code he will have to keep in mind all the variables in method. This line just made this reviewer to update variable value which is not a cheap operation for people.Also consider using LINQ here and replace it with:
int[] temp = factoradiac.Select(i => i + 1).ToArray();I wasn't strong enough to read through second class, so probably some my points will be applicable there also.
Code Snippets
this.data = new int[n];
for (int i = 0; i < n; ++i)
{
this.data[i] = i;
}this.data = Enumerable.Range(0, n).ToArray();public Permutation(int n)
{
this.data = new int[n];
...
this.order = n;
}
public Permutation(int n, int k)
{
this.data = new int[n];
this.order = this.data.Length;
...
}for (int i = 0; i < n; ++i)
{
temp[i] = ++factoradic[i]; // <-- Why ++ ???
}int[] temp = factoradiac.Select(i => i + 1).ToArray();Context
StackExchange Code Review Q#1352, answer score: 4
Revisions (0)
No revisions yet.