论坛首页 编程语言技术论坛

Trie树 应用 Phone List

浏览 1839 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-06-15  

Phone List

时间限制:5000 ms  |  内存限制:65536 KB
描述

Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another.

 

Let’s say the phone catalogue listed these numbers:

 

  • Emergency 911
  • Alice 97 625 999
  • Bob 91 12 54 26

In this case, it’s not possible to call Bob, because the central would direct your call to the emergency line as soon as you had dialled the first three digits of Bob’s phone number. So this list would not be consistent.

输入

The first line of input gives a single integer, 1 ≤ t ≤ 40, the number of test cases. Each test case starts with n , the number of phone numbers, on a separate line, 1 ≤ n ≤ 10000.

 

Then follows n lines with one unique phone number on each line. A phone number is a sequence of at most ten digits.

输出

For each test case, output “YES” if the list is consistent, or “NO” otherwise.

样例输入
2
3
911
97625999
91125426
5
113
12340
123440
12345
98346
样例输出
NO
YES
     这题是一个标准的Trie树,如果处理好的话用排序也可以过,话说效率 还是挺不错的,但这里要讲的是Tire树做法。字符串处理的算法有很多,Trie树和Trie图(也就是AC自动机)都是很高效的数据结构,后缀数组也 是,但是由于后缀数组较为复杂,实现起来也比较恼火。Trie树是一棵度 m ≥ 2 的树,它的每一层分支不是靠整个关键码的值来确定,而是由关键码的一个分量来确定。关键码可以是英文字母,也可以是数字(这里的数据我们当作字符处理)。 Trie的基本操作有插入,删除,查询,实现起来也是比较容易的。
     用动态添加节点北航的OJ能过,但是POJ过不了,听说用静态的,本人暂时不会哈。所以给出的是动态添加的方法。

     针对这一题来分析:

           题 意:给n个串,看是否有一个串是另一个串的前缀。因为数据量相对来讲比较大,如果用两两比较,会TL,所以 O(n^2)显然过不了这题。  字典树却很容易处理,但是这里在实现的时候 就有问题了,设置节点信息包括flag标志是否到达一个单词尾部,另外设置一个数组记录此结点的儿子结点的数组下标。在插入过程中就可以进行查询。

 

 

 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX 10

typedef struct TrieNode{
	bool isPhone;
	TrieNode *next[MAX];
	void initialTrie(){
		isPhone = false;
		for(int i = 0 ; i < MAX ; i++){
			next[i] = NULL;
		}
	}
}TrieNode;

bool isPrefixPhone = false;



void addWord(TrieNode *node,char *ch){
	if(node == NULL || *ch == '\0')
		return;
	TrieNode *p = node;
	int i,len;
	for(i = 0 ; i < (len=strlen(ch)) ; i ++){
		if(p->next[ch[i]-'0'] == NULL){
			TrieNode *tmp = (TrieNode*)malloc(sizeof(TrieNode));
			//初始化以temp为顶点节点的子树
			tmp->initialTrie();
			p->next[ch[i]-'0'] = tmp;	
		}else{		
			if(p->next[ch[i]-'0']->isPhone && i <= len - 1){
				isPrefixPhone = true;
				return;
			}
		}
		p = p->next[ch[i]-'0'];
	}
	p->isPhone = true;
	//如果先输入12,再输入1,那么就需要下面的代码进行判断
	for(i = 0 ; i < MAX ; i ++){
		if(p->next[i] != NULL){
			isPrefixPhone = true;
			return;
		}
	}
}


void delTree(TrieNode *root){
	for(int i = 0 ; i < MAX ; i ++){
		if(root->next[i] != NULL){
			delTree(root->next[i]);
		}
		delete root->next[i];
	}
}



int main(){
	int t,n,i;
	char s[11];
	scanf("%d",&t);
	TrieNode *root = (TrieNode*)malloc(sizeof(TrieNode));
	while(t--){	
		root->initialTrie();
		isPrefixPhone = false;
		scanf("%d",&n);
		for(i = 0 ; i < n ; i ++){
			scanf("%s",s);
			if(isPrefixPhone) continue;
			addWord(root,s);
		}
		printf(isPrefixPhone ? "NO\n":"YES\n");
		delTree(root);
	}
	return 0;
}

 

    网上大牛写的静态版

 

 

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int MAXNODE=500000;
    const int BRANCH=10;

    int Tree[MAXNODE][BRANCH],SIZE;
    bool Key[MAXNODE];
    bool Insert(char *str) {
        int Node=0;bool tof=false;
        for (int i=0;str[i];i++){
            int c=str[i]-'0';
            if(Tree[Node][c]==-1){
                Tree[Node][c]=++SIZE;tof=true;
                memset(Tree[SIZE],-1,sizeof(Tree[SIZE]));
            }
            if(Key[Node]) return false;
            Node=Tree[Node][c];
        }
        Key[Node]=true;
        return tof;
    }

    void Trie(){
        memset(Tree[0],-1,sizeof(Tree[0]));
        SIZE=0;
    }

    char str[15];
    int main()
    {
        int t,n;bool tof;
        scanf("%d",&t);
        while(t--){
            memset(Key,false,sizeof(Key));
            Trie();tof=true;
            scanf("%d",&n);
            for(int i=0;i<n;i++){
                scanf("%s",str);
                if(tof){
                    tof=Insert(str);
                }
            }
            if(tof) puts("YES");
            else puts("NO");
        }
    }
 

论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics