1. 程式人生 > >資料結構實訓——單詞檢索統計程式

資料結構實訓——單詞檢索統計程式

  1. /***********************************************************  
    * 版權所有 (C)2016,WuHao 
    *  
    * 專案名稱:單詞檢索統計程式  
    * 其它說明: 各個模組函式   
    * 作 者:    武昊  
    * 完成日期: 20161230  
    **********************************************************
    
    hao.h:
    /********************************************************* 
    * 版權所有 (C)2016,wuhao
    * 
    * 內容摘要:對各種引數進行初始化 
    * 檔名稱:hao.h
    * 檔案標識:hao.h
    * 其它說明:可以讀取txt檔案 
    * 當前版本: V8.0 
    * 作 者:  武昊 
    * 完成日期: 20161230
    * 
    ************************************************************/
    
    
    #include <stdio.h>
    #include <stdlib.h> 
    #include <string.h>  
    #define LIST_INIT_SIZE 500   /*線性表儲存空間的初始分配量*/ 
    #define LISTINCREMENT 10     /*線性表儲存空間的分配增量*/ 
    #define FILE_NAME_LEN 20        /*檔名長度*/ 
    #define WORD_LEN     20         /*單詞長度*/ 
    #define MaxStrSize   256  
    #define llength 110          /*規定一行有110個位元組*/ 
    #define MaxStr 258 
    #define WORD 21   
    typedef struct 
    {            
    	char ch[MaxStr];  /* ch是一個可容納256個字元的字元陣列 */           
    	int length;
    	
    } string; /* 定義順序串型別 */ 
    typedef struct 
    {      
    	char word[WORD];          /*儲存單詞,不超過20個字元*/     
    	int count;                 /*單詞出現的次數*/ 
    } elem_type;   
    typedef struct{      
    	elem_type *elem;           /*儲存空間基址*/     
    	int length;                /*當前長度*/      
    	int listsize;              /*當前分配的儲存容量*/ 
    } sqlist; 
    
    
    
    
    
    /********************************************************* 
    * 版權所有 (C)2016,wuhao
    * 
    * 檔名稱:word.cpp
    * 檔案標識:word.cpp
    * 內容摘要:單詞檢索
    * 其它說明:無 
    * 當前版本: V8.0 
    * 作 者:  武昊 
    * 完成日期: 20161230
    * 
    ************************************************************/
    
    
    
      #include"hao.h" 
     int sqlist_init(sqlist *sq, elem_type *et) 
    {      
    	sq->elem = et;     
    	sq->length = 0;     
    	return 0;} 
    /********************************************************* 
    * 功能描述:單詞新增
    * 輸入引數:變數i,j,結構體:sqlist,elem_type
    * 輸出引數:無 
    * 返回值  :0
    * 其它說明:無 
    ************************************************************/ 
    
    int sqlist_add(sqlist *sq, elem_type *et, char *word) {      
    	int i;     
    	int j;      
    	for (i = 0; i < sq->length; i++)     
    	{      /*當前單詞與加入的單詞相同,直接統計,不做插入 */         
    		if (strcmp(et[i].word, word) == 0)         
    		{              
    			et[i].count++;            
    			return 0;         
    		}         
    		if (strcmp(et[i].word, word) > 0)        
    		
    		{              
    			break;        
    		}     
    	}      
    	if (sq->length == LIST_INIT_SIZE)     
    	{          printf("空間不足,單詞[%s]插入失敗\n", word);        
    	return 0;     
    	}       
    	for (j = sq->length; j > i; j--)    
    	{         
    		memcpy(et+j, et+j-1, sizeof(elem_type)); 
    	}       
    	sq->length++;      
    	strcpy(et[i].word, word);     
    	et[i].count = 1;       
    	return 0; 
    }  
    /********************************************************* 
    * 功能描述:單詞輸出
    * 輸入引數:變數i,j,結構體:sqlist,elem_type
    * 輸出引數:無 
    * 返回值  :j
    * 其它說明:無 
    ************************************************************/ 
    
    int sqlist_count(sqlist *sq, elem_type *et) 
    {     
    	int i, j = 0;       
    	for(i=0;i<sq->length;i++)         
    		j=j+et[i].count;         
    	return j; 
    } 
    /********************************************************* 
    * 功能描述:建立文字文件
    * 輸入引數:檔案變數:fp,結構體:sqlist,elem_type,字串:file_name
    * 輸出引數:無 
    * 返回值  :0
    * 其它說明:無 
    ************************************************************/ 
      
    int creat_text_file() /*建立文字文件*/
    {          
    	elem_type w;          
    	sqlist s;           
    	char file_name[FILE_NAME_LEN + 1],yn;          
    	FILE *fp;           
    	printf("輸入要建立的檔名:");         
    	scanf("%s",file_name);         
    	fp=fopen(file_name,"w");           
    	yn='n'; /* 輸入結束標誌初值 */                
    	while(yn=='n'||yn=='N')                 
    	{                           
    		printf("請輸入一行文字:");                        
    		gets(w.word);                          
    		gets(w.word);                          
    		s.length=strlen(w.word);                          
    		fwrite(&w,s.length,1,fp);                         
    		fprintf(fp,"%c",10); /* 是輸入換行 */                           
    		printf("結束輸入嗎?y or n :");yn=getchar();                    
    	}            fclose(fp); /* 關閉檔案 */          
    	printf("建立檔案結束!\n");             
    	return 0; 
    }
    /********************************************************* 
    * 功能描述:文字單詞總彙
    * 輸入引數:字元:file_name[],word[],檔案變數:fp
    * 輸出引數:無 
    * 返回值  :0
    * 其它說明:無 
    ************************************************************/ 
      
     int substrsum()/*文字單詞彙總 */
    {       
    	 char file_name[FILE_NAME_LEN + 1];     
    	 char word[WORD_LEN+1];     
    	 FILE *fp;       
    	 int i;      
    	 int j,q=0;     
    	 int w,x,y=0;      
    	 elem_type et[LIST_INIT_SIZE];     
    	 sqlist sq;      
    	 sqlist_init(&sq, et);     
    	 printf("請輸入檔名:");    
    	 scanf("%s", file_name);    
    	 fp = fopen(file_name, "r");     
    	 if (fp == NULL)
    	 {         
    		 printf("開啟檔案失敗!\n");         
    		 return 0;    
    	 }      
    	 while (fscanf(fp, "%s", word) != EOF)
    	 {           
    		 sqlist_add(&sq, et, word);     
    	 }      
    	 fclose(fp);      
    	 printf(">>>>>>>>>>>>>>>>單詞<<<>>>>個數<<<<<<<<<<<\n");     
    	 for (i = 0; i < sq.length; i++)      
    	 {            
    		 x=strlen(et[i].word);              
    		 for(w=x-1;w>=0;w--)            
    			 if(et[i].word[w]<65||(et[i].word[w]>90&&et[i].word[w]<97)||et[i].word[w]>122)          
    			 {             
    				 et[i].word[w]=' ';          
    			 }           
    			 for(w=0;w<x;w++)              
    				 if (et[i].word[w]==' ')                 
    					 y++;              
    				 if(y==x)              
    				 {                  
    					 et[i].count=0;                  
    					 y=0;             
    				 }               
    				 else y=0;              
    				 if(et[i].count!=0)               
    					 printf("%20s%10d\n", et[i].word, et[i].count);else q++;      
    	 }       
    	 j=sqlist_count(&sq, et);       
    	 printf("\n>>>>>>>>>>>>>>>>>>%s的單詞總數為%d個\n",file_name,j);      
    	 printf("\n>>>>>>>>>>>>>>>>>>%s的非單詞個數為%d種\n",file_name,q);      
    	 printf("\n");     
    	 return 0; 
     } 
    /********************************************************* 
    * 功能描述:串匹配演算法
    * 輸入引數:變數i,j,串s1,s2,字元長度:length
    * 輸出引數:無 
    * 返回值  :0
    * 其它說明:無 
    ************************************************************/ 
     
     int partposition (string s1,string s2,int k) /*串匹配演算法*/
     {    
    	 int i,j;       
    	 i=k-1;       /* 掃描s1的下標,因為c中陣列下標是從0開始,串中序號相差1 */    
    	 j=0; /* 掃描s2的開始下標 */     
    	 while(i<s1.length && j<s2.length)    
    	 {
    		 if(s1.ch[i]==s2.ch[j])          
    		 {
    			 i++;j++;  /* 繼續使下標移向下一個字元位置 */        
    		 }    else       
    		 {            
    			 i=i-j+1; j=0;        
    		 } 
    	 }     
    	 if (j>=s2.length)       
    		 return i-s2.length;    
    	 else       
    		 return -1; /* 表示s1中不存在s2,返回-1 */       /* 表示s1中存在s2,返回其起始位置 */
     }  /* 函式結束 */
    /********************************************************* 
    * 功能描述:統計單次出現的個數
    * 輸入引數:串變數:s,t檔案變數:fp字元量:fname[]
    * 輸出引數:無 
    * 返回值  :0
    * 其它說明:無 
    ************************************************************/ 
      
     int substrcount() /* 統計單詞出現的個數 */ 
     {               
    	 FILE *fp;              
    	 string s,t; /* 定義兩個串變數 */             
    	 char fname[10];            
    	 int i=0,j,k;              
    	 printf("輸入文字檔名:");             
    	 scanf("%s",fname);             
    	 fp=fopen(fname,"r");              
    	 printf("輸入要統計計數的單詞:");             
    	 scanf("%s",t.ch);             
    	 t.length=strlen(t.ch);             
    	 while(!feof(fp)){                       
    		 memset(s.ch,'\0',110);                    
    		 fgets(s.ch,110,fp);                     
    		 s.length=strlen(s.ch);                      
    		 k=0;  /* 初始化開始檢索位置 */ 
    		 while(k<s.length-1)  /* 檢索整個主串S */                        
    		 {                         
    			 j=partposition(s,t,k); /* 呼叫串匹配函式 */                       
    			 if(j<0 ) break;                        
    			 else 
    			 {                                
    				 i++;  /* 單詞計數器加1 */                                
    				 k=j+t.length;  /* 繼續下一字串的檢索 */                           
    			 }         
    			 
    		 }             
    	 }           
    	 printf("\n單詞%s在文字檔案%s中共出現%d次\n",t.ch,fname,i); 
    	 return 0;  
     }  
    /********************************************************* 
    * 功能描述:檢索單詞出現的行號次數及位置
    * 輸入引數:串變數:s,t檔案變數:fp
    * 輸出引數:無 
    * 返回值  :0
    * 其它說明:無 
    ************************************************************/ 
     
     int substrint()  /* 檢索單詞出現在文字檔案中的行號、次數及其位置 */
     {          
    	 FILE *fp;             
    	 string s,t;   /* 定義兩個串變數 */          
    	 char fname[10];          
    	 int wz[20];   /* 存放一行中字串匹配的多個位置 */        
    	 printf("輸入文字檔名:");           
    	 int i,j,k,l,m;             
    	       scanf("%s",fname);           
    	 fp=fopen(fname,"r");            
    	 printf("輸入要檢索的單詞:");          
    	 scanf("%s",t.ch);          
    	 t.length=strlen(t.ch);          
    	 l=0;   /* 行計數器置0 */             
    	 while(!feof(fp))            
    	 { 
    		 /* 掃描整個文字檔案 */            
    		 memset(s.ch,'\0',110);            
    		 fgets(s.ch,110,fp);             
    		 s.length=strlen(s.ch);           
    		 l++;  /* 行計數器自增1 */           
    		 k=0; /* 初始化開始檢索位置 */          
    		 i=0; /* 初始化單詞計數器 */           
    		 while(k<s.length-1)  /* 檢索整個主串S */          
    		 {                    
    			 j=partposition(s,t,k);  /* 呼叫串匹配函式 */          
    			 if(j<0) break;                   
    			 else                    
    			 {                        
    				 i++; /* 單詞計數器加1 */wz[i]=j; /* 記錄匹配單詞位置 */                         
    				 k=j+t.length; /* 繼續下一字串檢索 */               
    			 }              
    		 }               
    		 if(i>0)                   
    		 {                     
    			 printf("行號:%d,次數:%d,起始位置分別為:",l,i);                   
    			 for(m=1;m<=i;m++)                    
    				 printf("第%4d個字元",wz[m]+1);                  
    		 }                   
    		 printf("\n");           
    	 }           
    	 printf("\n本軟體自定義110個位元組為一行\n\n");   
    	 return 0; 
     }
    
    
    /********************************************************* 
    * 功能描述:定位統計
    * 輸入引數:字元變數:t,switch case語句
    * 輸出引數:無 
    * 返回值  :0
    * 其它說明:無 
    ************************************************************/
    
    int substrio() 
     {          
    int substrcount(),substrint();       
    char t;        
    //while(1)         
    //{          
    printf("===============================================\n");                   
    printf("||文字檔案單詞字串的定位統計及定位||\n");                  
    printf("||================================||\n");                
    printf("||     a.     單詞出現次數        ||\n");                     
    printf("||                                ||\n");                     
    printf("||                                ||\n");                    
    printf("||     b.     單詞出現位置        ||\n");                
         printf("||                                ||\n");              
    printf("====================================\n");              
    printf("請輸入a或b:");                  
    scanf("%c%*c",&t);         
    switch(t)     
    {                            
    case 'a': substrcount();break;                  
    case 'b': substrint();break;                 
    default: return 0;          
    }        
    //}    
    return 0; 
     }   
     int main(void)
     {
    int creat_text_file(),substrsum(),substrio();             
    int a;           
    int t = 1;         
    while(t)     
    {                  
    printf("****************************************************\n");               
    printf("**************文字檔案單詞的檢索與計數**************\n");
    printf("╔━━━═━━━═━━━═━━━═━━━═━━━═╗\n");
        printf("┋   ╭─────╮      ╰★【1】建立文字文件    ┋\n");
        printf("┋   │●      ●│      ╰★【2】文字單詞彙總    ┋\n");
        printf("┋  ╱ ╭▼▼▼╮ ╲     ╰★【3】單詞定位        ┋\n");
        printf("┋ ╰┐│      │┌╯    ╰★【4】退出            ┋\n");
        printf("┋   │╰▲▲▲╯│                               ┋\n");
        printf("┋┗━            ┗━                            ┋\n");
        printf("╚━━━═━━━═━━━═━━━═━━━━━━━━╝\n");
        printf("請選擇(1~4):");               
    scanf("%d%*c",&a);      
    switch(a)       
    {                        
    case 1: creat_text_file();break;        
    case 2: substrsum();break;                  
    case 3: substrio();break;                             
    case 4: return 0;                            
    default:printf("選擇錯誤,重新選 \n");             
    }             
    }    
    return 0; 
     }