用于一组元素的数组的所有组合的算法

时间:2012-11-26 10:45:01

标签: arrays algorithm sorting

我想要一个像这样工作的算法:

给出了许多要素:

A B C D E F

算法应该生成包含这些元素的所有数组组合:

[A,B,C,D,E,F]
[AB,C,D,E,F]
[ABC,D,E,F]
[A,BC,D,E,F]
[A,B,C,DEF]
[ABCDEF]

无效的组合是(例如):

[AC,B,D,E,F]
[AB,BC,D,E,F]
[BC,DE,FA]

也就是说,元素应保持有序。

修改 我想在英语句子上使用该算法来检测复合名词。

例如:

On the table is a water jug.

应该被识别为以下单词类的序列。

Pronoun, Determiner, Noun, Verb, Determiner, Noun

但不是

Pronoun, Determiner, Noun, Verb, Determiner, Noun, Noun

2 个答案:

答案 0 :(得分:1)

将问题减少到这个:

对于n个字母,您之间有n-1个字母。 您需要选择是否在每个n-1位置放置一个分隔符。

伪代码将是这样的:

choose(set, size)
    if (size <= 0) return
    set1 = set
    set2 = set
    choose(set1+1, size-1);
    choose(set2+1, size-1);
    set1 = ',' U set1+1  //set1+1 here denotes the subset starting at second position
    set2 = ' ' U set2+1
    add set1, set2 to the output group

choose(A, n-1)调用。

答案 1 :(得分:1)

我认为这个问题可以通过递归来解决。以A,B,C,D,E,F为例。我们可以将A和B组合以形成新元素AB,其余元素C,D,E,F可以视为相同的问题并且递归地求解。我们也可以将A,B,C组合成一个新的元素ABC,剩下的元素是D,E,F。代码如下:

#include<iostream>
#include<string>
#include<vector>


using namespace std;

void sequential_combination(char input[],int start, int length,vector<string>& result)
{
     if(start>=length)
     {
        cout<<"[";
        for(int i=0;i<result.size()-1;++i)cout<<result[i]<<",";
        cout<<result[result.size()-1];
        cout<<"]";
        cout<<endl;
     }
     else
     {
         string prefix="";
         for(int i=start;i<length;++i)
         {
                 prefix+=input[i];
                 result.push_back(prefix);
                 sequential_combination(input,i+1,length,result);
                 result.pop_back();
         }
     }     
}

int main()
{

    char input[6]={'A','B','C','D','E','F'};
    vector<string> result;
    sequential_combination(input,0,6,result);
    getchar();
    getchar();
    return 0;
}

希望它有所帮助!