알아낼 수있었습니다. MSDN example을 기반으로하는 새로운 Combination 클래스를 만들었습니다.이 조합은 인덱스로 조합을 변환하거나 그 반대로도 변환 할 수 있습니다. 각 숫자 풀마다 별도의 색인이 검색됩니다. 그런 다음 모든 색인을 결합하여 크기가 다른 요소와의 조합을 나타냅니다.
풀 클래스 (요소 범위, 크기 등)를 나타내는 풀 클래스도 생성되었습니다. 풀 클래스 :
public class Pool {
public int From { get; set; }
public int To { get; set; }
public int Size { get; set; }
public int Numbers { get { return (To - From + 1); } }
public Pool(int From, int To, int Size) {
this.From = From;
this.To = To;
this.Size = Size ;
}
}
조합 클래스 :
class Combination {
public Pool[] Pools { get; set; }
public long[][] Data { get; set; } //First index represents pool index, second represents the numbers
public Combination(Pool[] Pools, long[][] Data) {
this.Pools = Pools;
this.Data = Data;
if (Data.GetLength(0) != Pools.Length) {
throw (new ArgumentException("Invalid data length"));
}
for (int i = 0; i < Data.GetLength(0); i++) {
if (Data[i].Length != Pools[i].Size) {
throw (new ArgumentException("Invalid data length"));
}
}
}
public static Combination FromIndex(long Index, Pool[] Pools) {
long[][] elements = new long[Pools.Length][];
long[] c = new long[Pools.Length - 1];
long cumulative = 1;
for (int i = 0; i < Pools.Length - 1; i++) {
c[i] = Combination.Choose(Pools[i].Numbers, Pools[i].Size);
checked {
cumulative *= c[i];
}
}
for (int i = Pools.Length - 1; i >= 1; i--) {
long ind = Index/cumulative;
Index -= ind * cumulative;
cumulative /= c[i - 1];
elements[i] = Combination.FromIndex(ind, Pools[i]);
}
elements[0] = Combination.FromIndex(Index, Pools[0]);
return (new Combination(Pools, elements));
}
public static long[] FromIndex(long Index, Pool Pool) {
long[] ans = new long[Pool.Size];
long a = (long)Pool.Numbers;
long b = (long)Pool.Size;
long x = GetDual((long)Pool.Numbers, (long)Pool.Size, Index);
for (int k = 0; k < Pool.Size; k++) {
ans[k] = LargestV(a, b, x);
x -= Choose(ans[k], b);
a = ans[k];
b--;
}
for (int k = 0; k < Pool.Size; k++) {
ans[k] = ((long)Pool.Numbers - 1) - ans[k];
}
//Transform to relative
for (int i = 0; i < ans.Length; i++) {
ans[i] += Pool.From;
}
return (ans);
}
private static long GetDual(long To, long Size, long m) {
return (Choose(To, Size) - 1) - m;
}
public static long Choose(long To, long Size) {
if (To < 0 || Size < 0)
throw new Exception("Invalid negative parameter in Choose()");
if (To < Size)
return 0; // special case
if (To == Size)
return 1;
long delta, iMax;
if (Size < To - Size) {
delta = To - Size;
iMax = Size;
} else {
delta = Size;
iMax = To - Size;
}
long ans = delta + 1;
for (long i = 2; i <= iMax; ++i) {
checked {
ans = (ans * (delta + i))/i;
}
}
return ans;
}
private static long LargestV(long a, long b, long x) {
long v = a - 1;
while (Choose(v, b) > x)
--v;
return v;
}
public long ToIndex() {
long Index = 0;
long cumulative = 1;
for (int i = 0; i < Pools.Length; i++) {
checked {
Index += ToIndex(i) * cumulative;
cumulative *= Combination.Choose(Pools[i].Numbers, Pools[i].Size);
}
}
return (Index);
}
public long ToIndex(int PoolIndex) {
long ind = 0;
for (int i = 0; i < Pools[PoolIndex].Size; i++) {
long d = (Pools[PoolIndex].Numbers - 1) - (Data[PoolIndex][i] - Pools[PoolIndex].From);
ind += Choose(d, Pools[PoolIndex].Size - i);
}
ind = GetDual(Pools[PoolIndex].Numbers, Pools[PoolIndex].Size, ind);
return (ind);
}
public override string ToString() {
string s = "{ ";
for (int i = 0; i < Data.Length; ++i) {
for (int k = 0; k < Data[i].Length; k++) {
s += Data[i][k] + " ";
}
if (i != Data.Length - 1) {
s += "| ";
}
}
s += "}";
return s;
}
}
행동이를 보려면 :
//Create pools
Pool[] pools = new Pool[2];
pools[0] = new Pool(1, 45, 5);
pools[1] = new Pool(1, 20, 1);
//Create a combination
long[][] data = new long[][] { new long[] { 41, 42, 43, 44, 45 }, new long[] { 20 } };
Combination combination = new Combination(pools, data);
//Get index from combination:
long index = combination.ToIndex();
Console.WriteLine("Index: " + index);
//Get combination from index:
Combination combFromIndex = Combination.FromIndex(index, pools);
Console.WriteLine("Combination: " + combFromIndex);
출력 :
Index: 24435179
Combination: { 41 42 43 44 45 | 20 }
내가 믿는 레머의 코드를 사용하여, 마지막 조합의 색인은 24,435보다 훨씬 클 것이고, 어떤 인덱스는 중복 된 숫자를 가진 순열로 매핑 될 것이기 때문에 또는 같은 순열로 매핑 될 것이지만 다른 순서로 그 숫자로 매핑 될 것이다. –
죄송합니다. 조합을 의미하는 순열을 보았습니다. 나는이 문제를 해결했다. –
인덱스 1은 "1,2,3,4,6,1"입니까, 아니면 "1,2,3,4,5,2"입니까? – Kaoru