【问题标题】:which is the best way to generate choices out of a given set of numbers?从给定的一组数字中产生选择的最佳方法是什么?
【发布时间】:2010-08-04 12:35:26
【问题描述】:

例如,如果给出了在 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.

谁能推荐一个快速算法?

【问题讨论】:

  • 是的。但为什么要投反对票??这不是编程题吗?
  • 不是反对者,但你的问题真的很模糊。当然,您已经编写了某种“输出”(为什么空间运行?为什么终止期?)但这可以是任何语言,而不仅仅是 C 或 C++。限制为这些语言意味着您有一些想要的 API(函数、类或模板?允许递归?)您没有共享。
  • 可能重复:stackoverflow.com/questions/1876474/… 至少看看它,以了解详细问题应包含哪些内容。
  • @mike 我放置了空格以明确输出大小不限于 2 或 3,我需要所有可能的组合。我是一名 c++ 程序员,因此希望有一个 c++ 代码.. 就是这样。
  • @Kirill:我很想看到 O(N^2) 的实现;有 2^N 组合要枚举。

标签: c++ c algorithm


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    你想找到幂集

    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 是一个详细解释它的链接。

    【讨论】:

      【解决方案3】:

      最快的是使用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;
      }
      

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

          谁能推荐一个快速算法?

          算法可以用多种语言表达,这是 Haskell 中的强大功能:

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

          【讨论】:

          • 或:power = filterM (const [False,True])
          【解决方案6】:

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

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

          答案 = sum(k = 1 to n) C(n,k)

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-02-04
            • 2010-09-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多