简体   繁体   English

组合算法

[英]combinations algorithm

I want to make simple sorting algorithm. 我想制作简单的排序算法。

given the input "abcde", I would like the output below. 如果输入“abcde”,我想要下面的输出。 could you tell me the algorithm for that? 你能告诉我算法吗?

arr[0] = "a"
arr[1] = "ab"
arr[2] = "ac"
arr[3] = "ad"
arr[4] = "ae"
arr[5] = "abc"
arr[6] = "abd"
arr[7] = "abe"
...
arr[n] = "abcde"

arr[n+1] = "b"
arr[n+2] = "bc"
arr[n+3] = "bd"
arr[n+4] = "be"
arr[n+5] = "bcd"
arr[n+5] = "bce"
arr[n+5] = "bde"
...
arr[n+m] = "bcde"
...
...

An algorithm for "generating Power Set" from an array is what you are looking for. 您正在寻找一种从阵列“生成电源组”的算法。 You can try Google or some other search engine to find the algorithm that best fits your needs. 您可以尝试使用Google或其他搜索引擎来查找最符合您需求的算法。

In C++ given the following routine: 在C ++中给出以下例程:

template <typename Iterator>
bool next_combination(const Iterator first, Iterator k, const Iterator last)
{
   /* Credits: Mark Nelson http://marknelson.us */
   if ((first == last) || (first == k) || (last == k))
      return false;
   Iterator i1 = first;
   Iterator i2 = last;
   ++i1;
   if (last == i1)
      return false;
   i1 = last;
   --i1;
   i1 = k;
   --i2;
   while (first != i1)
   {
      if (*--i1 < *i2)
      {
         Iterator j = k;
         while (!(*i1 < *j)) ++j;
         std::iter_swap(i1,j);
         ++i1;
         ++j;
         i2 = k;
         std::rotate(i1,j,last);
         while (last != j)
         {
            ++j;
            ++i2;
         }
         std::rotate(k,i2,last);
         return true;
      }
   }
   std::rotate(first,k,last);
   return false;
}

You can then proceed to do the following: 然后,您可以继续执行以下操作:

std::string s = "abcde";
for(std::size_t i = 1; i != s.size(); ++i)
{
   do
   {
      std::cout << std::string(s.begin(),s.begin() + i) << std::endl;
   }
   while(next_combination(s.begin(),s.begin() + i,s.end()));
}

Note: That you should expect to see 2^n-1 combinations, where n is the length of the array or string. 注意:您应该看到2 ^ n-1个组合,其中n是数组或字符串的长度。

You are describing a power set . 您正在描述一组电源 Here is some C++ code: 这是一些C ++代码:

#include <vector>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;

vector< string > string_powerset( string const &in ) {
    vector< string > result(1); // start output with one empty string
    result.reserve( 1 << in.size() ); // output size = 2^( in.size() )
    if ( result.capacity() != 1<<in.size() ) throw range_error( "too big" );

    for ( string::const_iterator it = in.begin(); it != in.end(); ++ it ) {
        size_t middle = result.size(); // duplicate what we have so far
        result.insert( result.end(), result.begin(), result.end() );

          // append current character onto duplicated output
        for_each( result.begin() + middle, result.end(),
           bind2nd( mem_fun_ref( &string::push_back ), * it ) );
    }
    return result;
}

Tested working :v) . 经过测试的工作:v)。 The range check isn't the best, but whatever. 范围检查不是最好的,但无论如何。

This code will tend to overflow, due to the exponential growth of the powerset, so you should only pass it short strings. 由于powerset的指数增长,此代码将倾向于溢出,因此您应该只传递短字符串。 The other posted answer avoids this problem by generating and returning one string at a time. 另一个发布的答案通过一次生成并返回一个字符串来避免此问题。 However, this is easier to understand, and using a far larger and more confusing piece of code would be premature optimization unless you actually have an overflow problem. 但是,这更容易理解,并且使用更大且更混乱的代码片段将是过早优化,除非您确实存在溢出问题。

EDIT: I wrote up a next_subset answer , and it looks nothing like Ben's. 编辑:写了一个next_subset答案 ,它看起来不像本的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM