我想要一个像这样工作的算法:
给出了许多要素:
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
答案 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;
}
希望它有所帮助!