/*字典树*/一些简单题

原理很简单,,,,,肯定能看懂,,,我觉得实现费点劲。。。。。

我的模板:

#include <iostream>

#include<bits/stdc++.h>

using namespace std;

#define  MAX  26

typedef struct TrieNode

{

int nCount;  // 该节点前缀 出现的次数

struct TrieNode *next[MAX]; //该节点的后续节点

} TrieNode;

TrieNode Memory[1000000]; //先分配好内存。 malloc 较为费时

int allocp = 0;

//初始化一个节点。nCount计数为1, next都为null

TrieNode * createTrieNode()

{

TrieNode * tmp = &Memory[allocp++];

tmp->nCount = 1;

for (int i = 0; i < MAX; i++)

tmp->next[i] = NULL;

return tmp;

}

void insertTrie(TrieNode * * pRoot, char * str)

{

TrieNode * tmp = *pRoot;

int i = 0, k;

//一个一个的插入字符

while (str[i])

{

k = str[i] - ‘a‘; //当前字符 应该插入的位置

if (tmp->next[k])

{

tmp->next[k]->nCount++;

}

else

{

tmp->next[k] = createTrieNode();

}

tmp = tmp->next[k];

i++; //移到下一个字符

}

}

int searchTrie(TrieNode * root, char * str)

{

if (root == NULL)

return 0;

TrieNode * tmp = root;

int i = 0, k;

while (str[i])

{

k = str[i] - ‘a‘;

if (tmp->next[k])

{

tmp = tmp->next[k];

}

else

return 0;

i++;

}

return tmp->nCount; //返回最后的那个字符  所在节点的 nCount

}

int main(void)

{

char s[30];

TrieNode *Root = createTrieNode();

while (gets(s) && s[0] != ‘0‘) //读入0 结束

{

insertTrie(&Root, s);

}

while (gets(s)) //查询输入的字符串

{

printf("%d\n", searchTrie(Root, s));

}

return 0;

}

这个方法很快。。。。。

/*有的题要用C++不用G++要不容易超内存*/

HDU1004:

稍稍变形。。。。。。

#include<stdio.h>

#include <string.h>

using namespace std;

typedef struct node

{

struct node *next[26];

int cnt;

}node;

node memory[100000];

int allocp;

int ans;

char an[30];

node *create()

{

node *tmp=&memory[allocp++];

for(int i=0;i<26;i++) tmp->next[i]=NULL;

tmp->cnt=0;

return tmp;

}

int inserttrie(node **proot,char *s)

{

node *tmp=*proot;

int i=0,k;

while(s[i])

{

k=s[i]-‘a‘;

if(tmp->next[k]);

else

{

tmp->next[k]=create();

}

if(i==strlen(s)-1)

{

tmp->next[k]->cnt++;

//printf("%d*\n",tmp->next[k]->cnt);

}

if(tmp->next[k]->cnt>=ans)

{

ans=tmp->next[k]->cnt;

strcpy(an,s);

//puts(an);

//printf("%d\n",tmp->next[k]->cnt);

}

tmp=tmp->next[k];

i++;

}

return ans;

}

int main()

{

int m;

char a[100];

node *root=create();

while(scanf("%d",&m)&&m!=0)

{

memset(memory,0,sizeof(memory));

allocp=0;

ans=0;

int i;

for(i=0;i<m;i++)

{

scanf("%s",a);

inserttrie(&root,a);

}

printf("%s\n",an);

}

return 0;

}

HDU1075 可以不用字典树做,,,,用pair就好了,,模拟。。。。

字典树注意比如输入fiw,,输出还是fiw;

#include<stdio.h>

#include <string.h>

using namespace std;

char a[15],b[15];

typedef struct node

{

char s[15];

struct node *next[26];

};

node memory[1000000];

int allocp=0;

node * create()

{

node * tmp=&memory[allocp++];

for(int i=0;i<26;i++) tmp->next[i]=NULL;

tmp->s[0]=‘\0‘;

return tmp;

}

void inserttrie(node ** proot,char *b)

{

node * tmp=*proot;

int i=0,k;

while(b[i])

{

k=b[i]-‘a‘;

if(tmp->next[k]);

else

tmp->next[k]=create();

if(i==strlen(b)-1) {strcpy(tmp->next[k]->s,a);} //printf("%s****\n",tmp->next[k]->s);

tmp=tmp->next[k];

i++;

}

}

int searchtrie(node *root,char *s)

{

if(root==NULL) return 0;

node* tmp = root;

int i=0,k;

while(s[i])

{

k=s[i]-‘a‘;

if(tmp->next[k])

{

tmp=tmp->next[k];

}

else return 0;

i++;

}

if(tmp->s[0]==0) return 0;

printf("%s",tmp->s);

return 1;

}

int main()

{

scanf("%s",a);

char c[10001];

char d[500];

node * root=create();

while(scanf("%s",a)==1)

{

if(strcmp(a,"END")==0) break;

scanf("%s",b);

int flag=0;

inserttrie(&root,b);

}

scanf("%s",a);

getchar();

while(1)

{

gets(c);

//printf("%s**\n",c);

if(c[0]==‘S‘&&c[1]==‘T‘&&c[2]==‘A‘&&c[3]==‘R‘&&c[4]==‘T‘) continue;

if(c[0]==‘E‘&&c[1]==‘N‘&&c[2]==‘D‘) break;

int t=0;

for(int i=0;i<strlen(c);i++)

{

if(c[i]>=‘a‘&&c[i]<=‘z‘)

{

d[t++]=c[i];

if(i==strlen(c)-1) {if(searchtrie(root,d)==0) printf("%s",d);}

}

else if((c[i-1]>=‘a‘&&c[i-1]<=‘z‘))

{

//printf("%s***\n",d);

if(searchtrie(root,d)==0) printf("%s",d);

printf("%c",c[i]);

memset(d,0,sizeof(d));

t=0;

}

else printf("%c",c[i]);

}

puts("");

}

return 0;

}

HDU4287

#include<stdio.h>

#include <string.h>

using namespace std;

char a[5005][10];

char b[10];

typedef struct node

{

struct node *next[10];

int cnt;

}node;

node memory[200000];

int allocp;

void bianhuan()

{

for(int i=0;i<strlen(b);i++)

{

if(b[i]==‘a‘||b[i]==‘b‘||b[i]==‘c‘) b[i]=‘2‘;

if(b[i]==‘d‘||b[i]==‘e‘||b[i]==‘f‘) b[i]=‘3‘;

if(b[i]==‘g‘||b[i]==‘h‘||b[i]==‘i‘) b[i]=‘4‘;

if(b[i]==‘j‘||b[i]==‘k‘||b[i]==‘l‘) b[i]=‘5‘;

if(b[i]==‘m‘||b[i]==‘n‘||b[i]==‘o‘) b[i]=‘6‘;

if(b[i]==‘p‘||b[i]==‘q‘||b[i]==‘r‘||b[i]==‘s‘) b[i]=‘7‘;

if(b[i]==‘t‘||b[i]==‘u‘||b[i]==‘v‘) b[i]=‘8‘;

if(b[i]==‘w‘||b[i]==‘x‘||b[i]==‘y‘||b[i]==‘z‘) b[i]=‘9‘;

}

}

node *create()

{

node *tmp=&memory[allocp++];

tmp->cnt = 0;

for(int i=0;i<10;i++)

{

tmp->next[i] = NULL;

}

return tmp;

}

void inserttrie(node **proot,char *s)

{

node *tmp=*proot;

int i=0,k;

while(s[i])

{

k=s[i]-‘0‘;

if(tmp->next[k]);

else tmp->next[k]=create();

tmp=tmp->next[k];

i++;

if(i==strlen(s))

{

tmp->cnt++;

}

}

}

int searchtrie(node *root,char *s)

{

if(root==NULL) return 0;

node *tmp=root;

int i=0,k;

while(s[i])

{

k=s[i]-‘0‘;

if(tmp->next[k])

tmp=tmp->next[k];

else return 0;

i++;

}

return tmp->cnt;

}

int main()

{

int m;

scanf("%d",&m);

int w1,w2;

while(m--)

{

memset(memory,0,sizeof(memory));

allocp=0;

node *root=create();

scanf("%d %d",&w1,&w2);

int i;

for(i=0;i<w1;i++)

scanf("%s",a[i]);

for(i=0;i<w2;i++)

{

scanf("%s",b);

bianhuan();

inserttrie(&root,b);

}

//printf("*\n");

for(i=0;i<w1;i++)

printf("%d\n",searchtrie(root,a[i]));

}

return 0;

}

字典树就差不多这样了。。。。。。。。。恩恩!





版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-08 09:02:16

/*字典树*/一些简单题的相关文章

hdu 1247:Hat’s Words(字典树,经典题)

Hat's Words Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7282    Accepted Submission(s): 2639 Problem Description A hat's word is a word in the dictionary that is the concatenation of exactly

poj 2503:Babelfish(字典树,经典题,字典翻译)

Babelfish Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 30816   Accepted: 13283 Description You have just moved from Waterloo to a big city. The people here speak an incomprehensible dialect of a foreign language. Fortunately, you have

hdu 1075:What Are You Talking About(字典树,经典题)

What Are You Talking About Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/204800 K (Java/Others)Total Submission(s): 12617    Accepted Submission(s): 4031 Problem Description Ignatius is so lucky that he met a Martian yesterday. But

LA、Remember the Word (字典树, 简单dp)

传送门 题意: 给你一个初始串 S,strlen(s) <= 3e5  然后给你 n 个单词. n <= 4000,  每个单词的长度不超过 100 : 问你这个初始串,分割成若干个单词的连接的方案:(这些单词必须是给定的n个单词中的任意一个,一个单词可以被使用多次.) 解: 将 n 个单词建个字典树: dp[ i ] 表示,S的 0 ~ i - 1 切割成若干个 单词的方案数: 枚举S, 枚举到 当前位置 i: 然后就在字典树找,以 S 的 i + 1 开始的, 能不能找到一个单词与之匹配:

HDU 1251 裸的字典树、入门题

裸的字典树还是挺简单的. 四个基本操作建立.查找.插入.删除 建立新结点我是用的c++中 new操作.当然也可以用malloc,都方便 不过指针阿.地址阿.这其中关系什么的我貌似还不是很清楚阿. 因为刚开始我的头结点也是定义的指针.然后程序就炸了.我不清楚原因呢. 有待弄清楚. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #includ

字典树的简单实现

Trie树,又称为字典树,是一种树形结构,是一种哈希树的变种,是一种用于快速检索的多叉树数据结构. 用于保存大量的字符串.它的优点是:利用字符串的公共前缀来节约存储空间. Trie的核心思想是空间换时间.利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的. 它有3个基本性质: 1.根节点不包含字符,除根节点外每一个节点都只包含一个字符. 2.从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串. 3.每个节点的所有子节点包含的字符都不相同. 搜索字典项目的方法为: (1)

hdu 5536 Chip Factory 字典树+bitset 铜牌题

Chip Factory Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1842    Accepted Submission(s): 833 Problem Description John is a manager of a CPU chip factory, the factory produces lots of chip

HDU 1251 统计难题(字典树入门模板题 很重要)

统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)Total Submission(s): 56382    Accepted Submission(s): 19709 Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的

[CQOI 2006]线段树之简单题

Description 有一个n个元素的数组,每个元素初始均为0.有m条指令,要么让其中一段连续序列数字反转--0变1,1变0(操作1),要么询问某个元素的值(操作2).例如当n=20时,10条指令如下: Input 第一行包含两个整数n,m,表示数组的长度和指令的条数,以下m行,每行的第一个数t表示操作的种类.若t=1, 则接下来有两个数L, R (L<=R),表示区间[L, R]的每个数均反转:若t=2,则接下来只有一个数I,表示询问的下 标.1<=n<=100,000,1<=