现在的位置: 首页 > 综合 > 正文

poj 2001 Shortest Prefixes (trie)

2012年09月26日 ⁄ 综合 ⁄ 共 1594字 ⁄ 字号 评论关闭

拿到这题,大致的画了画图,发现只要标记好每个节点出现的次数就好了。 

插入时,若字符存在,n++,若不存在建立新节点,他本身也为自己的前缀。

查找时,若next[k]->nCount!=1,说明其子节点有多个,无法确定唯一,则输出该字符,若nCount=1,则可以结束查找了。

code:

#include<cstdio>
#include<cstring>

char str[1001][21] ;
#define MAX 30 //字符集大小
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]->nCount ++ ;
        else
            p->next[k] = CreateTrieNode() ;
        p = p->next[k] ;
    }
}

//查找
void SearchTrie(TrieNode **pRoot, char *s){
    TrieNode *p ;
    p = *pRoot ;
    int i , k ;
    i = 0 ;
    while(s[i]){
        k = s[i++] - 'a' ;
        if(p->next[k]==NULL||p->next[k]->nCount==1){
            printf("%c", k+'a') ;
            break ;
        }
        else{
            p = p->next[k] ;
            printf("%c", k+'a') ;
        }
    }
    printf("\n") ;
}
int main(){
    int n = 0, i ;
    allocp = 0 ;

    TrieNode *root = NULL ;
    InitTrieRoot(&root) ;

    while(gets(str[n])&&str[n][0])
        InsertTrie(&root, str[n++]) ;
    for(i=0; i<n; i++){
        printf("%s ", str[i]) ;
        SearchTrie(&root, str[i]) ;
    }
    return 0 ;

抱歉!评论已关闭.