zoukankan      html  css  js  c++  java
  • UVa 11732

    称号:给你一些话,给你一个字符串比较函数,所有的话都当奇偶校验,什么是比较次数。

    分析:弦、特里。

    首先。看数据大小,假设正常的发现线索,会议TLE和MLE。

                由于,常规的字典树深度为1000,并且有可能会有大量的指正空间浪费。

                所以,採用树的压缩算法(左兄弟,右孩子)。能够提高执行效率。

                然后。在字典树上同级就可以。统计时,能够先建树再统计,或者边建树边统计。

                这里我选用边建树边统计的方法(网上大量的做法,都是先建树再统计的,搜索求解)

                每次插入单词时。它仅仅与前面插入的单词比較;单词的比較次数为当中每一个字母的比較次数的和。

                单词中每一个字母的比較次数。就是这个字母的根节点包括的单词个数。

                单词比較函数例如以下:

    int strcmp(char *s, char *t)
    {
        int i;
        for (i=0; s[i]==t[i]; i++)
            if (s[i]=='')
                return 0;
        return s[i] - t[i];
    }
                由于比較函数如上,计算时要注意下面几点:

                1.同样长度为L的两个单词比較代价为2L-1。出最后一次外要进行s结束的推断;

                2.单词的比較长度应该为strlen(str)+1,结束符也是比較的一环;

                3.假设两个单词同样,则多计算一次结束推断。比較次数+1。

    注意:使用LL,否则数据会溢出。

    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    typedef long long LL;
    
    char words[1010];
    
    /* Trie define */  
    #define nodesize 4444444    //节点个数 
      
    typedef struct node1  
    {
    	char    value;
    	int     size;
    	int     count;
        node1*  Lchild;
    	node1*  Rchild;
    }tnode;  
    tnode dict[nodesize];
      
    class Trie  
    {  
        private:  
    		LL     count;
            int    size;  
            tnode* root;
        public:  
            Trie() {initial();}   
            void initial() {  
                memset( dict, 0, sizeof(dict) );  
                size=0;count=0LL;root=newnode(0);
            }  
            tnode* newnode( char c ) {
    			dict[size].value = c;
    			return &dict[size ++];
    		}  
            void insert( char* word, int L ) {  
                tnode* now = root->Rchild,*save = root; 
                int same = 1;
                for ( int i = 0 ; i <= L ; ++ i ) { 
    				if ( !now ) {
    					save->Rchild = newnode(word[i]);
    					now = save->Rchild;
    					now->count = 1;
    					same = 0;
    				}else {
    					if ( i ) count += now->count;
    					count += now->count ++;
    					while ( now->Lchild && now->value != word[i] )
    						now = now->Lchild;
    					if ( now->value != word[i] ) {
    						now->Lchild = newnode(word[i]); 
    						now = now->Lchild;
    						same = 0;
    					}
    				}
    				save = now;
    				now = save->Rchild;
                }
                if ( same ) save->size ++;
                count += save->size;
            }  
            LL query() {return count;}
    }trie;  
    /* Trie  end */  
    
    int main()
    {
    	int Case = 1,N;
    	while ( scanf("%d",&N) != EOF ) {
    		if ( !N ) break;
    		
    		trie.initial();
    		for ( int i = 0 ; i < N ; ++ i ) {
    			scanf("%s",words);
    			trie.insert(words,strlen(words));
    		}
    		
    		printf("Case %d: %lld
    ",Case ++,trie.query());
    	}
    	return 0;
    }
    

    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    [Java解惑]数值表达式
    Java使用LdAP获取AD域用户
    LDAP Error Codes
    Excel向上取整
    java中的三种取整函数
    Dwz手册的补充说明和常见问题
    【转】BSON数据格式
    go语言合并两个数组
    vscode远程修改文件('file': A system error occured )
    [转]Linux 桌面玩家指南:20. 把 Linux 系统装入 U 盘打包带走
  • 原文地址:https://www.cnblogs.com/yxwkf/p/4821897.html
Copyright © 2011-2022 走看看