資料結構實訓——單詞檢索統計程式
阿新 • • 發佈:2019-01-26
-
/*********************************************************** * 版權所有 (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; }