UVA 10391 trie树
2015-09-09 13:13
232 查看
这个题目就是按照字典序从小到大给你n个字符串 让你找出其中敲好由其他俩个字符串组成的字符串并且输出
这里讲述三种方法 可以自行做出比较
1.暴力 这种方法是最慢的 是第三种方法的时间的10+倍 而且是最麻烦的 需要严谨耳朵逻辑思维和编码能力
2.灵活利用set string 这种方法速度还是可以的 但是也是下面这种方法的3倍左右
3.trie 树的结果 也就是利用单词的前缀进行匹配 这种方法是最快的
#include <cstdio>
#include <cstring>
const int sonnum = 26;
char word[120005][30];
struct trie
{
bool term;
struct trie *son[sonnum];
};
trie* create_trie()
{
trie *temp = new trie;
temp -> term = false;
for(int i = 0;i <sonnum;i++)
{
temp -> son[i] =NULL;
}
return temp;
}
void insert_word(trie *pnt,char s[],int len)
{
trie *temp = pnt;
for(int i = 0;i <len;i++)
{
if(temp -> son[s[i] - 'a'] == NULL)
temp -> son[s[i] - 'a'] = create_trie();
temp = temp -> son[s[i] - 'a'];
}
temp -> term = true;
}
bool find(trie *pnt ,char s[],int len)
{
trie *temp = pnt;
for(int i = 0;i <len ;i ++)
{
if(temp -> son[s[i] - 'a'] == NULL)
return false;
temp = temp -> son[s[i] - 'a'];
}
if(temp -> term)
return true;
return false;
}
int main()
{
int n = 0;
trie *t = create_trie();
while(scanf("%s",word
) == 1)
{
insert_word(t,word
,strlen(word
));
n++;
}
for(int i = 0;i < n;i ++)
{
char s1[30],s2[30];
int len = strlen(word[i]);
for(int j = 1;j < len ;j ++)
{
int k;
for(k = 0;k < j;k++)
{
s1[k] = word[i][k];
}
s1[k] = '\0';
for(k = j;k < len;k ++)
{
s2[k-j] = word[i][k];
}
s2[k-j] = '\0';
if(find(t,s1,strlen(s1))&&find(t,s2,strlen(s2)))
{
printf("%s\n",word[i]);
break;
}
}
}
return 0;
}
这个题目就是按照字典序从小到大给你n个字符串 让你找出其中敲好由其他俩个字符串组成的字符串并且输出
这里讲述三种方法 可以自行做出比较
1.暴力 这种方法是最慢的 是第三种方法的时间的10+倍 而且是最麻烦的 需要严谨耳朵逻辑思维和编码能力
#include <iostream> #include <string> #include <vector> #include <algorithm> using namespace std; int main() // { freopen("in.txt","r",stdin); vector<string>vs[26]; string s; while(getline(cin,s)) if(s.length())vs[s[0]-'a'].push_back(s); for(int i=0; i<26; i++) { if(vs[i].size()>=2) { for(int j=1; j<vs[i].size(); j++) { bool judge = true; for(int k=0; k<j; k++) { if(vs[i][j].find(vs[i][k])==0)//string里面的函数find 查找是不是子串 如果是的话 返回第一个字符的位置 因为这个是前串 所以是0 { string t = vs[i][j].substr(vs[i][k].length());//参数可以是一个或者俩个 一个是取子串的位置 一个是长度(如果没有的话就是一直取到末尾) if(!vs[t[0]-'a'].empty()) { for(int z=0; z<vs[t[0]-'a'].size(); z++) { if(vs[t[0]-'a'][z]==t) { if(judge)cout << vs[i][j] << endl; judge = false; } } } } } } } } return 0; }
2.灵活利用set string 这种方法速度还是可以的 但是也是下面这种方法的3倍左右
#include<iostream> #include<set> using namespace std; int main() { freopen("in.txt","r",stdin); set<string> s; string tmp; while (cin >> tmp) s.insert(tmp); set<string>::iterator it = s.begin(); for (it; it != s.end(); it++) { tmp = *it; for (int i = 1; i < tmp.length(); i++) { if (s.find(tmp.substr(0, i)) != s.end() && s.find(tmp.substr(i, tmp.length() - i)) != s.end()) { cout << tmp << endl; break; } } } return 0; }
3.trie 树的结果 也就是利用单词的前缀进行匹配 这种方法是最快的
#include <cstdio>
#include <cstring>
const int sonnum = 26;
char word[120005][30];
struct trie
{
bool term;
struct trie *son[sonnum];
};
trie* create_trie()
{
trie *temp = new trie;
temp -> term = false;
for(int i = 0;i <sonnum;i++)
{
temp -> son[i] =NULL;
}
return temp;
}
void insert_word(trie *pnt,char s[],int len)
{
trie *temp = pnt;
for(int i = 0;i <len;i++)
{
if(temp -> son[s[i] - 'a'] == NULL)
temp -> son[s[i] - 'a'] = create_trie();
temp = temp -> son[s[i] - 'a'];
}
temp -> term = true;
}
bool find(trie *pnt ,char s[],int len)
{
trie *temp = pnt;
for(int i = 0;i <len ;i ++)
{
if(temp -> son[s[i] - 'a'] == NULL)
return false;
temp = temp -> son[s[i] - 'a'];
}
if(temp -> term)
return true;
return false;
}
int main()
{
int n = 0;
trie *t = create_trie();
while(scanf("%s",word
) == 1)
{
insert_word(t,word
,strlen(word
));
n++;
}
for(int i = 0;i < n;i ++)
{
char s1[30],s2[30];
int len = strlen(word[i]);
for(int j = 1;j < len ;j ++)
{
int k;
for(k = 0;k < j;k++)
{
s1[k] = word[i][k];
}
s1[k] = '\0';
for(k = j;k < len;k ++)
{
s2[k-j] = word[i][k];
}
s2[k-j] = '\0';
if(find(t,s1,strlen(s1))&&find(t,s2,strlen(s2)))
{
printf("%s\n",word[i]);
break;
}
}
}
return 0;
}
相关文章推荐
- IOS 利用UIWebView和javascript的技术实现打开网页快速定位到某处(id)
- javaweb开发中关于字符编码出现乱码问题的总结
- TCP协议下---客户端与服务端一问一答聊天
- Win 10系统设置不了默认浏览器怎么办?Win 10系统设置默认浏览器的方法
- 软件测试常用术语
- 冒泡排序
- nginx的autoindex-目录浏览还有其它两个参数
- java生成缩略图,旋转,水印,截图
- 公开课—未来iOS开发掌舵者Swift
- 一站式服务让互联网家装更美丽
- ida 中hexview快速跳转到内存地址
- 推送技术-icomet学习和分析
- 配置ipvsadm服务
- 零基础学python-13.2 手动迭代:iter和next
- Leetcode Number of 1 Bits
- 零基础学python-13.2 手动迭代:iter和next
- HTTP 状态字
- 中国文化的未来
- hadoop笔记3-yarn执行流程
- cisco设备显示直接相邻的设备