ACM 字典树 Phone List & Hat’s Words
来源:互联网 发布:数据网站 编辑:程序博客网 时间:2024/06/10 02:39
字典树:又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。
典型应用:统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。
优点:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
基本性质:
1.根节点不包含字符,除根节点外每一个节点都只包含一个字符。
2.从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
3.每个节点的所有子节点包含的字符都不相同。
基本模板:(来自百度百科)
#define MAX 26//字符集大小typedef struct TrieNode{ int nCount;//记录该字符出现次数 struct TrieNode* next[MAX];}TrieNode; TrieNode Memory[1000000];int allocp=0; /*初始化*/void InitTrieRoot(TrieNode* *pRoot){ *pRoot=NULL;} /*创建新结点*/TrieNode* CreateTrieNode(){ int i; TrieNode *p; p=&Memory[allocp++]; p->nCount=1; for(i=0;i<MAX;i++) { p->next[i]=NULL; } return p;} /*插入*/void InsertTrie(TrieNode* *pRoot,char *s){ int i,k; TrieNode*p; if(!(p=*pRoot)) { p=*pRoot=CreateTrieNode(); } i=0; while(s[i]) { k=s[i++]-'a';//确定branch if(!p->next[k]) p->next[k]=CreateTrieNode(); else p->next[k]->nCount++; p=p->next[k]; }} //查找int SearchTrie(TrieNode* *pRoot,char *s){ TrieNode *p; int i,k; if(!(p=*pRoot)) { return0; } i=0; while(s[i]) { k=s[i++]-'a'; if(p->next[k]==NULL) return 0; p=p->next[k]; } return p->nCount;}
HDU 1671 Phone List
题目大意:(例题带入)有2组数据,第一组数据有3个电话号码,问是否存在一个号码是另一个的前缀,若存在则不合适,输出NO。
思路:字典树,在建树的时候直接判断了...
#include <iostream>#define MAX 10using namespace std;bool flag;typedef struct Trie_Node{ bool isphone; struct Trie_Node *next[MAX]; }Trie;void insert(Trie *root,char *phone){ Trie *p=root; while(*phone!='\0') { if(p->next[*phone-48]==NULL) { Trie *temp=(Trie *)malloc(sizeof(Trie)); temp->isphone=false; for(int i=0;i<MAX;i++) temp->next[i]=NULL; p->next[*phone-48]=temp; } if(p->isphone==true) flag=true; p=p->next[*phone-48]; phone++; } p->isphone=true; for(int i=0;i<MAX;i++) { if(p->next[i]!=NULL) { flag=true; break; } } }void del(Trie *root){ for(int i=0;i<MAX;i++) { if(root->next[i]!=NULL) del(root->next[i]); } free(root);}int main(int argc, char *argv[]){ int t; scanf("%d",&t); while(t--) { int i; int n; char phone[11]; Trie *root=(Trie *)malloc(sizeof(Trie)); root->isphone=false; flag=false; for(i=0;i<MAX;i++) root->next[i]=NULL; scanf("%d",&n); for(i=0;i<n;i++) { scanf("%s",phone); if(flag!=true) insert(root,phone); } if(flag==true) printf("NO\n"); else printf("YES\n"); del(root); } return 0;}
HDU 1247 Hat’s Words
题目大意:输入直到EOF结束,判断是否存在两个组合可以组成另一个字符串。
思路:先把所有字符串都存下来建树,然后从根走到每个叶子结点记下来比较。
#include<iostream>#include<string.h>#include<stdlib.h>#include<stdio.h>#include<algorithm>using namespace std;const int MAX=26;typedef struct Trie_Node{ bool isWord; struct Trie_Node *next[MAX];}Trie;char s[50010][50];void insert(Trie *root,char *word){ Trie *p=root; int i=0; while(word[i]!='\0') { if(p->next[word[i]-'a']==NULL) { Trie *temp=(Trie *)malloc(sizeof(Trie)); for(int j=0;j<MAX;j++) temp->next[j]=NULL; temp->isWord=false; p->next[word[i]-'a']=temp; } p=p->next[word[i]-'a']; i++; } p->isWord=true;}bool search(Trie *root,char *word){ Trie *p=root; for(int i=0;word[i]!='\0';i++) { if(p->next[word[i]-'a']==NULL) return false; p=p->next[word[i]-'a']; } return p->isWord;}void del(Trie *root){ for(int i=0;i<MAX;i++) { if(root->next[i]!=NULL) del(root->next[i]); } free(root);}int main(){ int i,j; int cnt=0; char str[50]; Trie *root=(Trie *)malloc(sizeof(Trie)); for(i=0;i<MAX;i++) root->next[i]=NULL; root->isWord=false; while(scanf("%s",s[cnt])!=EOF) { insert(root,s[cnt++]); } for(i=0;i<cnt;i++) { int len=strlen(s[i]); for(j=1;j<len-1;j++) { char temp1[50]={'\0'}; char temp2[50]={'\0'}; strncpy(temp1,s[i],j); strncpy(temp2,s[i]+j,len-j); if(search(root,temp1)&&search(root,temp2)) { printf("%s\n",s[i]); break; } } } del(root); return 0;}
阅读全文
0 0
- ACM 字典树 Phone List & Hat’s Words
- HDU ACM 1247-Hat’s Words-字典树(Trie)
- Hat’s Words(字典树)
- Hat’s Words(字典树)
- hdu Hat‘s Words(字典树)
- 【字典树】 hdu1247 Hat’s Words
- Hat’s Words hdu1247 字典树+搜索
- HDU 1247 Hat’s Words(字典树)
- hdu 1247 字典树 Hat’s Words
- HDU1247-Hat’s Words(字典树)
- HDU 1247 Hat’s Words 字典树
- Hat’s Words(hdu1247字典树)
- hdu1247 Hat’s Words (字典树)
- hdu 1247 Hat’s Words 字典树
- HDU 1247 Hat’s Words(字典树)
- hdu1247 Hat’s Words(字典树)
- [HDOJ 1247] Hat’s Words [字典树]
- hdu 1247 Hat’s Words(字典树)
- 2017开始起航,HPB加油
- 设计模式-单例模式
- 汝欲去学诗,工夫在诗外--JAVA
- c++ winpcap开发(4)
- 【栈队列】判断出栈顺序的合法性
- ACM 字典树 Phone List & Hat’s Words
- java clone()
- Java事务的类型
- 二分法的简单实现
- /*Oracle查询语句*/
- 14读书笔记之碎片的生命周期:
- PAT甲级 1031
- Sparse LDA
- Material Design之Toolbar