在不生成所有ncr组合的情况下查找特定组合的索引

时间:2013-04-04 17:06:12

标签: c#-4.0 ienumerable combinations

我试图找到特定组合的索引,而不生成所有可能组合的实际列表。例如:1到5的2个数字组合产生1,2; 1,3,1,4,1,5; 2,3,2,4,2,5..so..on。如果我的猜测正确,每个组合都有自己的索引从零开始。我想找到该索引而不为给定组合生成所有可能的组合。我正在用C#编写,但我的代码会在飞行中生成所有可能的组合。如果n和r类似于80和9,这将是昂贵的,我甚至无法枚举实际范围。是否有任何可能的方法来查找索引而不生成该特定索引的实际组合

public int GetIndex(T[] combination)
                    {
                        int index = (from i in Enumerable.Range(0, 9)
                                      where AreEquivalentArray(GetCombination(i), combination)
                                      select i).SingleOrDefault();

                        return index;

                    }

1 个答案:

答案 0 :(得分:1)

我用简单的语言找到了自己问题的答案。这很简单,但似乎在我的情况下是有效的。选择方法是从其他网站带来的,虽然它生成了n个项目的组合计数r:

public long GetIndex(T[] combinations)
        {
            long sum = Choose(items.Count(),atATime);
            for (int i = 0; i < combinations.Count(); i++)
            {
                sum = sum - Choose(items.ToList().IndexOf(items.Max())+1 - (items.ToList().IndexOf(combinations[i])+1), atATime - i);
            }

            return sum-1;

        }
private long Choose(int n, int k)
        {
            long result = 0;
            int delta;
            int max;
            if (n < 0 || k < 0)
            {
                throw new ArgumentOutOfRangeException("Invalid negative parameter in Choose()");
            }
            if (n < k)
            {
                result = 0;
            }
            else if (n == k)
            {
                result = 1;
            }
            else
            {
                if (k < n - k)
                {
                    delta = n - k;
                    max = k;
                }
                else
                {
                    delta = k;
                    max = n - k;
                }
                result = delta + 1;
                for (int i = 2; i <= max; i++)
                {
                    checked
                    {
                        result = (result * (delta + i)) / i;
                    }
                }
            }
            return result;
        }