题目:给你一些小写字母构成的单词,输出其中可以拆成两个单词的单词。
分析:字符串、字典树。
首先,利用字典树储存字符;
然后,按字典序枚举所有每个单词的所有可拆情况,判断拆除结果是不是单词即可。
说明:注意数组的大小。
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
char words[120004][256];
/* Trie define */
#define nodesize 400004 //节点个数
#define dictsize 26 //字符集大小
typedef struct node1
{
int flag; //值域
node1* next[dictsize];
}tnode;
tnode dict[nodesize];
int ID[256];
class Trie
{
private:
int max;
int size;
tnode* root;
public:
Trie() {makeID(); initial();}
void makeID() {
for ( int i = 0; i < 26 ; ++ i )
ID['a'+i] = i;
}
void initial() {
memset( dict, 0, sizeof( dict ) );
root=NULL; size=0; root=newnode();
}
tnode* newnode() {return &dict[size ++];}
void insert( char* word, int L ) {
tnode* now = root;
for ( int i = 0 ; i < L ; ++ i ) {
if ( !now->next[ID[word[i]]] )
now->next[ID[word[i]]] = newnode();
now = now->next[ID[word[i]]];
}now->flag = 1;
}
int query( char* word, int L ) {
tnode* now = root;
for ( int i = 0 ; i < L ; ++ i ) {
if ( !now->next[ID[word[i]]] ) return 0;
now = now->next[ID[word[i]]];
}return now->flag;
}
}trie;
/* Trie end */
int main()
{
trie.initial();
int L,count = 0;
while ( gets(words[count]) ) {
trie.insert( words[count], strlen(words[count]) );
count ++;
}
for ( int k = 0 ; k < count ; ++ k ) {
int L = strlen(words[k]);
for ( int i = 1 ; i < L ; ++ i ) {
if ( trie.query(words[k], i ) && trie.query(words[k]+i, L-i ) ) {
printf("%s\n",words[k]);
break;
}
}
}
//system("pause");
return 0;
}