题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1247 ,比较简单的字典树。
刚学字典树不久,多做题练练手。
解法:
先输入所有的字符串,建树。然后对所有的字符串进行枚举,将该字符串的前i位与后len-i位分为两个字符串,如果这两个字符串都在树中,则输出该字符串。由于题中给的数据是按照字典序的,所以不用考虑这点。
这里用到了strncpy()函数——strncpy 是 C语言的库函数之一,来自 C语言标准库,定义于 string.h,char *strncpy(char *dest, char *src, int n),把src所指字符串的前n个字节复制到dest所指的数组中,并返回指向dest的指针。(from 百度百科)
#include <iostream> #include <cstdio> #include <vector> #include <queue> #include <stack> #include <cmath> #include <string> #include <string.h> #include <algorithm> using namespace std; #define LL __int64 const int maxn = 50000 + 5; const int sigma_size = 26; struct Trie { int ch[maxn][sigma_size]; bool isEnd[maxn]; int size; void init() { size = 1; memset(ch[0] , 0 , sizeof(ch[0])); memset(isEnd , 0 , sizeof(isEnd)); } int index(char c) { return c - ‘a‘; } void insert(char *s) { int i , rt; for(i = rt = 0 ; s[i] != ‘\0‘ ; i++) { int c = index(s[i]); if(!ch[rt][c]) { memset(ch[size] , 0 , sizeof(ch[size])); ch[rt][c] = size++; } rt = ch[rt][c]; } isEnd[rt] = 1; } bool find(char *s) { int i , rt; for(i = rt = 0 ; s[i] != ‘\0‘ ; i++) { int c = index(s[i]); if(!ch[rt][c]) return false; rt = ch[rt][c]; } return isEnd[rt]; } } trie; char s[maxn][50]; char str[50]; int main() { int n; trie.init(); for(n = 0 ; scanf("%s" , s[n]) != EOF ; n++) { trie.insert(s[n]); } for(int i = 0 ; i <= n ; i++) { int len = strlen(s[i]); for(int j = 1 ; j < len ; j++) { memset(str , 0 , sizeof(str)); strncpy(str , s[i] , j); if(trie.find(str) && trie.find(s[i] + j)) { printf("%s\n" , s[i]); break; } } } return 0; }
时间: 2024-10-12 10:59:21