hdu1075 字典树

就是单词查找对应的单词


一开始用数组写的字典树结果超内存,运行时错误,数组已经到极限,不能扩大了,代码如下:

#include<cstdio>
#include<cstring>

const int maxnode=15000;
const int sigma_size=27;

char c[10000][15];

struct Trie{
	int ch[maxnode][sigma_size];
	int val[maxnode];
	int sz;
	Trie(){sz=1;memset(ch[0],0,sizeof(ch[0]));
	}
	int idx(char c){
		return c-'a';
	}
	
	void insert(char *s,int v){
		int u=0,n=strlen(s);
		for(int i=0;i<n;i++){
			int c=idx(s[i]);
			if(!ch[u][c]){
				memset(ch[sz],0,sizeof(ch[sz]));
				val[sz]=0;
				ch[u][c]=sz++;
			}
			u=ch[u][c];
		}
		val[u]=v;
	}
	
	int find(char *s){
		int u=0,n=strlen(s);
		for(int i=0;i<n;i++){
			int c=idx(s[i]);
			if(!ch[u][c])
			return 0;
			u=ch[u][c];
			
		}
		if(val[u]){
			return val[u];
		}
		return 0;
	}
};


int main()
{
	struct Trie root;
	char t[100],tt[100],k=0;
	while(scanf("%s",t)){
		if(strcmp(t,"START")==0){
			continue;
		}
		if(strcmp(t,"END")==0){
			break;
		}
		scanf("%s",tt);
		strcpy(c[k++],t);
		root.insert(tt,k);
	}
	int ct=0;
	while(gets(t)){
		if(strcmp(t,"START")==0){
			continue;
		}
		if(strcmp(t,"END")==0){
			break;
		}
		for(int i=0;i<strlen(t);i++){
			if(!(t[i]>='a'&&t[i]<='z'))
			{
				tt[ct]='\0';
				int j=root.find(tt);
				if(j==0){
					printf("%s",tt);
				}
				else{
					printf("%s",c[j-1]);
				}
				printf("%c",t[i]);
				ct=0;
				tt[0]='\0';
			}
			else
			tt[ct++]=t[i];
		
		}
		printf("\n");
		
	}
	return 0;
}

虽然已经喜欢上这种写法,可是还得改成指针形式的,就不会超内存了。。。。,哎,无语了。

代码如下:

#include <stdio.h>
#include <string>
#include <string.h>
#include <iostream>
using namespace std;
struct Trie
{
    struct Trie *child[26];
    char s[100];
    int n;
    int flag;
};
Trie *root;
void insert_trie(char *str,char *word)
{
    int len = strlen(str);
    Trie *cur,*newnode;
    cur = root;
    for(int i = 0; i < len; i++)
    {
        if(cur->child[str[i] - 'a'] != 0)
        {
            cur = cur->child[str[i] - 'a'];
            if(i == len-1)
            {
                strcpy(cur->s,word);
                cur->flag = 1;
            }
        }
        else
        {
            newnode = new Trie;
            for(int j = 0; j < 26; j++)
            {
                newnode->child[j] = 0;
            }
            cur->child[str[i] - 'a'] = newnode;
            cur = newnode;
            cur->flag = 0;//就是这里之前没有初始化。然后等到后面判断的时候出错了。
            if(i == len-1)
            {
                strcpy(cur->s,word);
                cur->flag = 1;
            }
        }
    }
}
char * find_return(char *str)
{
    int len = strlen(str);
    Trie *cur;
    cur = root;
    for(int i = 0; i < len ;i++)
    {
        if(cur->child[str[i] - 'a'] != 0)
        {
            cur = cur->child[str[i]-'a'];
        }
        else
            return "no find";
    }
    if(cur->flag)
    {
        return cur->s;
    }
    else
    {
        return "no find";
    }
}
int main()
{
    char dic[20],word[20];
    char ch = '0';
    char ans[26];
    int flag = 0;
    int isbegin;
    int k = 0;
    root = new Trie;
    memset(ans,0,sizeof(ans));
    for(int i = 0; i < 26; i++)
    {
        root->child[i] = 0;
    }
    root->flag = 0;
    root->n = 0;
    memset(root->s,0,sizeof(root->s));
    while(scanf("%s",dic) == 1)
    {
        if(strcmp(dic,"END") == 0)
        break;
        if(strcmp(dic,"START") != 0)
        {
            scanf("%s",word);
            insert_trie(word,dic);
        }

    }
    getchar();
    while(scanf("%c",&ch) == 1)
    {
        isbegin = 1;
        if(ch == 'S')
        {
            gets(dic);
            isbegin = 0;
        }
        if(ch == 'E')
        {
            break;
        }
        if(ch <= 122 && ch >= 97)
        {
            ans[k++] = ch;
            flag = 1;
        }
        if((ch > 122 || ch < 97) && isbegin)
        {
            if(flag)
            {

                flag = 0;
                if(strcmp(find_return(ans),"no find") != 0)
                printf("%s",find_return(ans));
                else
                   printf("%s",ans);
                memset(ans,0,sizeof(ans));
                k = 0;

            }
            printf("%c",ch);
     
        }

    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值