大数据检索(窗口界面界面演示型)

单词(词组)检索

现在有一个英文字典(每个单词都是由小写的'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]='\0';

    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]!='\0';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]='\0';

            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,"\n"); //将所有排好序的单词存于磁盘中

                else        fprintf(out,"     ");

                fprintf(out,"(%d)%-35s %-5d",j,(*p).word,(*p).count); 

                

                //在窗口中输出所有的已排好序的单词

                /*if(j%2==0)  printf("\n"); 

                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]='\0';

        a[i].mount=0;

    }       

    struct TrieNode *q;

    q=root;

    for(i=0;str[i]!='\0';i++)//根据str在树中搜索:是否存在这个单词

    {   if(q->next[str[i]-'a']!=NULL)

           q=q->next[str[i]-'a'];  

       else

       {  printf("没有这个单词\n"); break;}//如果单词还未遍历结束(str[i]!='\0'),

                                         //就指向了NULL,说明该单词不在“文档”中(即不在字典树中)

    }

    if(str[i]=='\0')

    {   printf("文档中单词%s共有%d个\n",str,q->count);//(第2问)**输出以单词str[]的个数



                   printf("文档中以单词%s为前缀的单词有:\n",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("\n以单词%s为前缀的频率最高的10个单词为单词:\n",str);

            for(i=0;i<10;i++)

            {   printf("(%d)%-10s ",i,a[i].pl);

                printf("%d\n",a[i].mount);

            }

        } 

        //(第4问)输出以单词str为前缀的频率最高的10个单词为单词*******************/

    }

}



int main()

{   

    /***********************测试建树的时间***********************************/

                   double duration;

                  clock_t start= clock();//******运行时间测试开始

    char s[50]={'\0'};



    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\n",duration ); 

    fclose(fp);

    /**************************************************************************/



    out=fopen("单词排序.txt","w");//打开一个文档,存放所有单词的按字母排序

    long zonggong;  

    zonggong=bianli(root);//遍历字典树

    printf("\n总共有%d个单词\n",zonggong);//输出总共的单词个数

    

    for(i=0;i<10;i++)//对字符数组pinlv b进行初始化(pinlv b 存放频率最高的十个单词及其频率)

    {    

        for(k=0;k<50;k++)

            b[i].pl[k]='\0';

        b[i].mount=0;

    } 

    //(第5问)在递归算法中将频率最高的10个单词记录在b[j].pl中

            digui(root,b);

            printf("全部单词中频率最高的10个单词为单词:\n");//输出全部单词中频率最高的10个单词为单词

            for(i=0;i<10;i++)

    {   

        printf("(%d)%-10s ",i,b[i].pl);

        printf("%d\n",b[i].mount);

    }

            printf("\n");

    

    pd=pd-1;//digui(root,b)后pd一直保持为1

    char panduan; 

    char str[50]={'\0'};//存放要查找的单词

    panduan='y';

    while(panduan=='y')

    {    

        printf("请输入要查找的单词:");

        scanf("%s",str);

                        //(2,3,4问)输出文档中以***为前缀的所有单词,并输出其中频率最高的10个单词    

        chazhao(root,str);    

        printf("\n是否继续?y/n:");    

        do

        {  getchar();

            panduan=getchar();//仅输入一个字符,不允许多输入

                           if(!(panduan=='y'||panduan=='n'))          

              printf("输入字符错误,请重新输入(y/n)!");

        }while( !((panduan=='y')||(panduan=='n')) );

    }        

        return 0;

}

 

你可能感兴趣的:(大数据)