题目大意 给定一个词典,要求找出所有的复合词,即恰好有两个单词连接而成的单词
分析
第一种方法 使用集合查看当前单词的分解手否存在
#include<iostream>
#include<algorithm>
#include<set>
#include<string>
#include<string.h>
#include<map>
#define maxn 120000+10
using namespace std;
string st[maxn];
int main()
{
set<string>se;
int cur = 0;
while (cin >> st[cur]) {
se.insert(st[cur++]);
}
for (int i = 0; i < cur; i++) {
for (int j = 0; j < st[i].length(); j++) {
string str1 = st[i].substr(0, j);
string str2 = st[i].substr(j);
if (se.count(str1) && se.count(str2)) {
cout << st[i] << endl; break;
}
}
}
return 0;
第二种方法使用哈希函数
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#define maxn 120000+10
#define maxh 500000
using namespace std;
int head[maxh], ne[maxn];
string st[maxn],word[maxn];
int cur,n;
void initial() {
cur = 0;
memset(head, -1, sizeof(head));
}
int Hash(string s) { //获取表头;
unsigned int seed = 31;
unsigned int ha = 0;
for (int i = 0; s[i] != 0; i++) {
ha = ha * seed + (s[i]); //为什么乘以奇数-避免冲突
}
return ha % maxh;
}
void add(string s) {
int id = Hash(s);
st[cur] = s;
ne[cur] = head[id], head[id] = cur++;
}
bool find(string s) {
int id = Hash(s);
//if (head[id] == -1)return false;
for (int i = head[id]; i != -1; i = ne[i])
if (st[i] == s)
return true;
return false;
}
int main() {
n = 0;
initial();
while (cin >> word[n])
add(word[n++]);
for (int i = 0; i < n; i++) {
for (int j = 1; j < word[i].size(); j++) {
string str1 = st[i].substr(0, j);
string str2 = st[i].substr(j);
if (find(str1) && find(str2)) {
cout << word[i] << endl;
break;
}
}
}
return 0;
}
第三种 也可以使用状态数组+map对应
#include<iostream>
#include<algorithm>
#include<set>
#include<string>
#include<string.h>
#include<map>
#define maxn 120000+10
using namespace std;
map<string, bool> ha;
int main()
{
int cur = 0;
while (cin >> st[cur]) {
ha[st[cur++]] = 1;
}
for (int i = 0; i < cur; i++) {
for (int j = 1; j < st[i].size(); j++) {
string str1 = st[i].substr(0, j);
string str2 = st[i].substr(j);
if (ha[str1] && ha[str2]) {
cout << st[i] << endl;
break;
}
}
}
return 0;
}