这是从一组给定数字中产生选择的最佳方法吗?

时间:2010-08-04 12:35:26

标签: c++ c algorithm

例如,如果给出所有选择在1到5之间,答案就是这样......

1,2,3,4,5,  
1-2,1-3,1-4,1-5,2-3,2-4,2-5,3-4,3-5,4-5,  
1-2-3,1-2-4,1-2-5,1-3-4,
.....,
1-2-3-4-5.

任何人都可以提出快速算法吗?

6 个答案:

答案 0 :(得分:18)

只需从一个生成所有整数(如果要包含空集,则为零)到 2 ^ N - 1 。您的集合由数字中的设置位指示。例如,如果您有5个元素{A,B,C,D,E},则数字6 = 00110将代表子集{C,D}。

答案 1 :(得分:1)

你想找到powerset

In mathematics, given a set S, the power set (or powerset) of S, written , 
P(S), , is the set of all subsets of S

有一种算法可以在此link找到功率集。

You basically take first element say 1 and find a all subsets {{},{1}}. Call this 
power set
Take next element 2 and add to powerset and get {{2},{1,2}} and take union
 with powerset.
{{},{1}} U {{2},{1,2}} = {{},{1},{2},{1,2}}

但上面的答案中描述了一种简单的方法。 Here是一个可以详细解释的链接。

答案 2 :(得分:1)

最快的方法是使用template metaprogramming,这将交换编译时间和代码大小以执行时间。但这只适用于少数组合,你必须提前知道它们。但是,你说“快”:)

#include <iostream>
using namespace std;

typedef unsigned int my_uint;

template <my_uint M>
struct ComboPart {
    ComboPart<M-1> rest;

    void print() {
        rest.print();
        for(my_uint i = 0; i < sizeof(my_uint) * 8; i++)
            if(M & (1<<i)) cout << (i + 1) << " ";
        cout << endl;
    }
};

template <>
struct ComboPart<0> {
    void print() {};
};

template <my_uint N>
struct TwoPow {
    enum {value = 2 * TwoPow<N-1>::value};
};

template <>
struct TwoPow<0> {
    enum {value = 1};
};

template <my_uint N>
struct Combos {
    ComboPart<TwoPow<N>::value - 1> part;
    void print() {
        part.print();
    }
};

int main(int argc, char *argv[]) {
    Combos<5> c5 = Combos<5>();
    c5.print();

    return 0;
}

这个在编译时构造所有组合。

答案 3 :(得分:0)

你想要的是在组合学中称为chooseThisthis可以帮助您入门。

答案 4 :(得分:0)

  

任何人都可以提出快速算法吗?

算法可以用多种语言表示,这里是Haskell中的幂集:

power [] = [[]]

power (x:xs) = rest ++ map (x:) rest
  where rest = power xs

答案 5 :(得分:0)

您想要组合,而不是排列(即{1,2}与{2,1}相同)

C(n,k)= n!/(k!(n-k)!)

答案=总和(k = 1到n)C(n,k)

      ( i.e. C(n,1)+C(n,2)...+C(n,n) )