zoukankan      html  css  js  c++  java
  • 大数据检索(窗口界面界面演示型)

    单词(词组)检索

    现在有一个英文字典(每个单词都是由小写的'a'-'z'组成) ,单词量很大,达到 100 多万的单词,而且还有很多重复的单词。

    此外,我们现在还有一些 Document,每个 Document 包含一些英语单词。

    针对这个问题,请你选择合适的数据结构,组织这些数据,使时间复杂度和空间复杂度

    尽可能低,并且解决下面的问题和分析自己算法的时间复杂度。

    1)基本型问题

    (1)选择合适的数据结构,将所有的英文单词生成一个字典 Dictionary。

    (2)给定一个单词,判断这个单词是否在字典 Dictionary中。如果在单词库中,输出这个单词总共出现的次数。否则输出 NO扩展:

    2)扩展型问题

    (3)给定一个单词,按字典序输出字典 Dictionary 中所有以这个单词为前缀的单词。例如,如果字典 T={a,aa, aaa, b, ba}, 如果你输入 a,那么输出应该为{a, aa, aaa}。

    (4)给定一个单词,输出在Dictionary 中以这个单词为前缀的单词的出现频率最高的10个单词,对于具有相同出现次数的情况,按照最近(即最后)插入的单词优先级比较高的原则输出。

    (5)输出 Dictionary 中出现次数最高的 10个单词。

    程序所能达到的功能:

    (1)建立字典

    1)查单词的出现频

    3)输出以单词为的所有单词

    4及其中率最高的十个单词

    5全部单词率最高的十个单词

    //注:在工程项目文件中放入待排序单词的tex文档

    #include<stdio.h>
    #include<string.h>
    #include<malloc.h>
    #include<time.h>
    FILE *out;//设置全局变量,用于递归程序
    static int pd=0;//递归搜索全部单词中频率最高的10个单词为单词后,pd 仁然保持为1
    struct TrieNode
    {               char c;
        char word[50];
        struct TrieNode  *next[26];
        long count;
    };
    typedef struct 
    {
        char pl[50];
        long mount;
    }PINLV;
    typedef PINLV pinlv[10];
    pinlv b;//设置全局变量,用于递归程序
    
    void chushihua(TrieNode *&p)
    {                int i;
        (*p).c='#';
        for(i=0;i<50;i++)
        p->word[i]='';
        for(i=0;i<26;i++)
        p->next[i]=NULL;
        p->count=0;
    }
    
    struct TrieNode* JLTrieNode(TrieNode *root,char s[50])
    {                int i,j;
        struct TrieNode *q,*p;
        q=root;    
        for(i=0;s[i]!='';i++)
        {
            if(q->next[s[i]-'a']!=NULL)
                q=q->next[s[i]-'a'];
            else 
            {   p=(struct TrieNode *)malloc(sizeof(struct TrieNode));
                q->next[s[i]-'a']=p;
                p->c=s[i];     p->count=0;//初始化节点值
                for(j=0;j<50;j++)
                    p->word[j]='';
                for(j=0;j<26;j++)
                    p->next[j]=NULL;
                    q=q->next[s[i]-'a'];
            }    
        }
        q->count++;
        strcpy(q->word,s);                
        return root;
    }
    
    long bianli(struct TrieNode *root)//遍历字典树并将单词按字母表顺序输出
    {    
        int i;    
        static long j=0,zonggong=0;
        struct TrieNode *p;
                     for(i=0;i<26;i++)
        {    p=root->next[i];
                if(p!=NULL)
            {   if((*p).count!=0) //***********
                {      
                    if(j%2==0)  fprintf(out,"
    "); //将所有排好序的单词存于磁盘中
                    else        fprintf(out,"     ");
                    fprintf(out,"(%d)%-35s %-5d",j,(*p).word,(*p).count); 
                    
                    //在窗口中输出所有的已排好序的单词
                    /*if(j%2==0)  printf("
    "); 
                    else printf("           ");
                    printf("(%d)%-20s ",j,(*p).word);  
                    printf("%-4d",(*p).count);
                    */
                    zonggong+=(*p).count;
                    j++;
                }
                zonggong=bianli(p);
            }
        }
        return zonggong;
    }
    
    void digui(struct TrieNode *q, pinlv &a)
    {   
                       int i,j,k; 
        if((*q).c=='#')   
            pd=1;
                      struct TrieNode *p;
        j=0;/**********444444444444444444444444*/
        for(i=0;i<26;i++)
        {    p=q->next[i];
            if(p!=NULL)
            {   if((*p).count!=0) //***********
                {   if(pd!=1)//(3)输出以单词***为前缀的所有单词***3333333333333333333333
                      printf("%s ",(*p).word);//(若q为根节点,则可以用于遍历整个字典树)                           
                    //*****将频率最高的10个单词记录在a[j].pl中********444444444444*/
                    for(j=0;j<10;j++)
                    {   if((*p).count>a[j].mount)
                        {   for(k=9;k>=j+1;k--)
                            {   strcpy(a[k].pl,a[k-1].pl);                         
                                a[k].mount=a[k-1].mount;
                            }
                            strcpy(a[j].pl,(*p).word); 
                            a[j].mount=(*p).count;
                            break;
                        }              
                    }
                    //********4444444444444444444444444444************************/        
                }
            digui(p,a);
            }
        }    
    }
    
    void chazhao(struct TrieNode *root,char str[50])
    {    int i,j,pan=0; 
        pinlv a;//(第4问)**************************
        for(i=0;i<10;i++)//对字符数组pinlv a进行初始化(pinlv a中存放以***为前缀的频率最高的10个单词)
        {    for(j=0;j<50;j++)
            a[i].pl[j]='';
            a[i].mount=0;
        }       
        struct TrieNode *q;
        q=root;
        for(i=0;str[i]!='';i++)//根据str在树中搜索:是否存在这个单词
        {   if(q->next[str[i]-'a']!=NULL)
               q=q->next[str[i]-'a'];  
           else
           {  printf("没有这个单词
    "); break;}//如果单词还未遍历结束(str[i]!=''),
                                             //就指向了NULL,说明该单词不在“文档”中(即不在字典树中)
        }
        if(str[i]=='')
        {   printf("文档中单词%s共有%d个
    ",str,q->count);//(第2问)**输出以单词str[]的个数
    
                       printf("文档中以单词%s为前缀的单词有:
    ",str);//(第3问)**输出以单词str[]为前缀的单词
            digui(q,a);//(3,4问)在递归程序中输出以单词str[]为前缀的所有单词,
                                     //并且记录以单词str为前缀的频率最高的10个单词为单词于pinlv a中
            
            //(第4问)输出以单词str为前缀的频率最高的10个单词为单词********************/
            if(a[0].mount==0) 
                printf("!!!没有以单词%s为前缀的单词 ",str);
            else
            {   printf("
    以单词%s为前缀的频率最高的10个单词为单词:
    ",str);
                for(i=0;i<10;i++)
                {   printf("(%d)%-10s ",i,a[i].pl);
                    printf("%d
    ",a[i].mount);
                }
            } 
            //(第4问)输出以单词str为前缀的频率最高的10个单词为单词*******************/
        }
    }
    
    int main()
    {   
        /***********************测试建树的时间***********************************/
                       double duration;
                      clock_t start= clock();//******运行时间测试开始
        char s[50]={''};
    
        int i,k;
        struct TrieNode *root;
        FILE *fp;
        fp=fopen("文档.txt","r");
                      root=(struct TrieNode *)malloc(sizeof(struct TrieNode));
        chushihua(root);//初始化头结点指针
        while(!feof(fp))//从文档中换行读取数据
        {    
            fscanf(fp,"%s",s);
            root=JLTrieNode(root,s);//(第1问)建立字典树
        };
        
        clock_t finish = clock();//*****运行时间测试结束
        duration = (double)(finish-start);//CLOCKS_PER_SEC;
                      printf( "建树时间为: %5.3f ms
    ",duration ); 
        fclose(fp);
        /**************************************************************************/
    
        out=fopen("单词排序.txt","w");//打开一个文档,存放所有单词的按字母排序
        long zonggong;  
        zonggong=bianli(root);//遍历字典树
        printf("
    总共有%d个单词
    ",zonggong);//输出总共的单词个数
        
        for(i=0;i<10;i++)//对字符数组pinlv b进行初始化(pinlv b 存放频率最高的十个单词及其频率)
        {    
            for(k=0;k<50;k++)
                b[i].pl[k]='';
            b[i].mount=0;
        } 
        //(第5问)在递归算法中将频率最高的10个单词记录在b[j].pl中
                digui(root,b);
                printf("全部单词中频率最高的10个单词为单词:
    ");//输出全部单词中频率最高的10个单词为单词
                for(i=0;i<10;i++)
        {   
            printf("(%d)%-10s ",i,b[i].pl);
            printf("%d
    ",b[i].mount);
        }
                printf("
    ");
        
        pd=pd-1;//digui(root,b)后pd一直保持为1
        char panduan; 
        char str[50]={''};//存放要查找的单词
        panduan='y';
        while(panduan=='y')
        {    
            printf("请输入要查找的单词:");
            scanf("%s",str);
                            //(2,3,4问)输出文档中以***为前缀的所有单词,并输出其中频率最高的10个单词    
            chazhao(root,str);    
            printf("
    是否继续?y/n:");    
            do
            {  getchar();
                panduan=getchar();//仅输入一个字符,不允许多输入
                               if(!(panduan=='y'||panduan=='n'))          
                  printf("输入字符错误,请重新输入(y/n)!");
            }while( !((panduan=='y')||(panduan=='n')) );
        }        
            return 0;
    }
  • 相关阅读:
    20169218 2016-2017-2 《网络攻防实践》第八周学习总结
    20169218 2016-2017-2 《网络攻防实践》第七周学习总结
    20169218 2016-2017-2 《网络攻防实践》第六周学习总结
    20169218 2016-2017-2 《网络攻防实践》第五周学习总结
    20169218 2016-2017-2 《网络攻防实践》第四周学习总结
    十三周作业—使用Metaspoit攻击MS08-067
    20169206 2016-2017-2 《网络攻防实践》课程总结
    《网络攻防》第十四周作业-免杀
    《网络攻防》 第十二周作业 SQL注入
    《网络攻防》 第十一周作业
  • 原文地址:https://www.cnblogs.com/IThaitian/p/3602518.html
Copyright © 2011-2022 走看看