資料結構------建立一個詞索引表
阿新 • • 發佈:2019-02-20
最近複習資料結構與演算法,就把《資料結構(C語言版)》(清華大學,嚴蔚敏)拿出來看,在串的那一章的最後有一個程式設計題--------建立一個詞索引表,寫了一下,程式碼如下。、
檔案1:define.h
內容:各種資料型別的定義
////////////////////////////////////////////////// // // 資料型別的定義 // //////////////////////////////////////////////// //////////////// #define MaxBookNum 1000 // 假設只對1000本書建立索引表 #define MaxKeyNum 2500 // 索引表的最大容量 #define MaxLineNum 500 // 書目串的最大長度 #define MaxWordNum 10 // 詞表的最大容量 // 書目型別的定義 typedef struct Book { char id[10] ; // 書號 char name[MaxLineNum] ; // 書名 } Book ; //書目表的定義 typedef struct BookList { Book book[MaxBookNum] ; // 儲存書目的表 int number ; // 書目數量 }BookList ; // 關鍵字索引對應的書目id typedef struct IdIndex { char id[10] ; struct IdIndex * next ; } IdIndex ; // 索引型別定義 typedef struct BookIndex { char index[50] ; IdIndex * head ; } BookIndex ; // 索引表 typedef struct BookIndexList { BookIndex bookindex[MaxKeyNum] ; // 索引項儲存資訊 int number ; // 索引項的書目 } BookIndexList ; // 詞表 typedef struct WordList { char Word[MaxWordNum][20] ; int number ; } WordList ; // 關鍵字表 typedef struct KeyWordList { char keyword[20][20] ; int number ; } KeyWord ;
檔案2:implenment.cpp
內容:各種函式的定義
///////////////////////////////////////////////// // // 實現主要函式 // /////////////////////////////////////////////////// //////////// #include "define.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <malloc.h> // 從檔案中讀入詞表資訊 void GetWordInfo( WordList * wordlist ) { int i = 0 ; char str[1000] ; // 開啟檔案 FILE * pf = fopen("word.txt","r+") ; if( pf == NULL ) { printf("開啟檔案word.txt失敗!\n") ; exit(0) ; } // 讀取檔案中的內容 while( feof(pf) != EOF ) { if( fgets( str , 1000 , pf ) ) { strcpy( wordlist->Word[i] , str ) ; if( wordlist->Word[i][strlen(wordlist->Word[i])-1] == '\n' ) { wordlist->Word[i][strlen(wordlist->Word[i])-1] = '\0' ; // 去掉每個詞最後的換行符 } i++ ; } else { break ; } } wordlist->number = i ; // 詞表的長度 } // 從檔案中讀入書目串 void GetBookInfo( BookList * booklist ) { int i = 0 ; int j = 0 ; int count = 0 ; int k = 0 ; char str[1000] = { '\0' } ; // 開啟檔案 FILE * pf = fopen( "bookinfo.txt" , "r+" ) ; if( pf == NULL ) { printf("開啟檔案失敗!\n") ; exit(0) ; } // 讀取檔案中的內容 while( feof( pf ) != EOF ) { if( fgets( str , 1000 , pf ) ) { if( str[strlen(str)-1] == '\n' ) { str[strlen(str)-1] = '\0' ; // 去掉讀取的一條書目字串最後的一個換行符 } while( str[j] != ' ' ) { booklist->book[i].id[j] = str[j] ; j++ ; } booklist->book[i].id[j] = '\0' ; count = j + 1 ; while( str[count] != '\0' ) { booklist->book[i].name[k++] = str[count++] ; } booklist->book[i].name[k] = '\0' ; i++ ; j = 0 ; k = 0 ; strcpy( str , "" ) ; } else { break ; } } booklist->number = i ; // 書目的數量 } // 系統初始化 void InitSystem( BookList * booklist , WordList * wordlist ) { // 從檔案bookinfo.txt中讀取書目資訊 GetBookInfo( booklist ) ; // 從檔案word.txt中讀取詞表資訊 GetWordInfo( wordlist ) ; printf("書目資訊:\n") ; for( int i = 0 ; i < booklist->number ; i++ ) { printf("%s %s\n", booklist->book[i].id , booklist->book[i].name ) ; } printf("詞表資訊:\n") ; for( i = 0 ; i < wordlist->number ; i++ ) { printf("%s\n" , wordlist->Word[i]) ; } } // 將一個書目名進行分割 void CutBookName( Book * book , KeyWordList * keywordlist ) { int i = 0 ; int j = 0 ; int k = 0 ; while( book->name[i] != '\0' ) { if( book->name[i] == ' ' ) { keywordlist->keyword[j][k] = '\0' ; k = 0 ; j++ ; i++ ; continue ; } keywordlist->keyword[j][k++] = book->name[i++] ; } keywordlist->keyword[j++][k] = '\0' ; keywordlist->number = j ; } // 判斷一個單詞是否為關鍵字 bool is_Key( char * word , WordList * wordlist ) { int i = 0 ; for( i = 0 ; i < wordlist->number ; i++ ) { if( strcmp( wordlist->Word[i] , word ) == 0 ) { return false ; } } return true ; } // 將一個書目名按照詞表過濾得到該書目名的關鍵字表 void GetBookKey( KeyWordList * keyword , WordList * wordlist , KeyWordList * lastkeyword ) { int i = 0 ; lastkeyword->number = 0 ; // 初始化關鍵字表的書目 for( i = 0 ; i < keyword->number ; i++ ) { if( is_Key( keyword->keyword[i] , wordlist) ) // 判斷當前字串是否為關鍵字 { strcpy( lastkeyword->keyword[lastkeyword->number++] , keyword->keyword[i] ) ; } } // 輸出一些中間結果 /* printf("某書目關鍵字表:\n") ; for( i = 0 ; i < lastkeyword->number ; i++ ) { printf("%s ",lastkeyword->keyword[i] ) ; } printf("\n") ; */ } // 判斷索引表中是否存在某個關鍵字 // 若存在,返回該索引項的下標;否則返回-1 int key_is_found( BookIndexList * bookindexlist , char * key ) { for( int i = 0 ; i < bookindexlist->number ; i++ ) { if( strcmp( key , bookindexlist->bookindex[i].index ) == 0 ) { return i ; } } return -1 ; } // 初始化索引表 void InitBookIndexList( BookIndexList * bookindexlist ) { bookindexlist->number = 0 ; } // 將一條書目資訊插入索引表 void HandleOneBookToIndexList( Book * book , KeyWordList * lastkeyword , BookIndexList * bookindexlist , WordList * wordlist ) { KeyWordList keywordlist ; CutBookName( book , &keywordlist ) ; // 將書目資訊進行分詞 GetBookKey( &keywordlist , wordlist , lastkeyword ) ; // 將分詞得到的單詞進行過濾得到該書目的關鍵字 for( int i = 0 ; i < lastkeyword->number ; i++ ) { int pos = key_is_found( bookindexlist , lastkeyword->keyword[i] ) ; if( pos >= 0 ) // 該關鍵字在索引表中存在 { IdIndex * idindex = (IdIndex*)malloc(sizeof(IdIndex)) ; if( !idindex ) { printf("申請記憶體失敗!\n") ; exit(0) ; } idindex->next = NULL ; strcpy( idindex->id , book->id ) ; IdIndex * tmp = bookindexlist->bookindex[pos].head->next ; bookindexlist->bookindex[pos].head->next = idindex ; idindex->next = tmp ; } else { // 初始化該關鍵字的索引列表 bookindexlist->bookindex[bookindexlist->number].head = ( IdIndex *)malloc(sizeof(IdIndex)) ; if( !bookindexlist->bookindex[bookindexlist->number].head ) { printf("申請記憶體失敗!") ; exit(0) ; } bookindexlist->bookindex[bookindexlist->number].head->next = NULL ; IdIndex * idindex2 = (IdIndex*)malloc(sizeof(IdIndex)) ; if( !idindex2 ) { printf("申請記憶體失敗!\n") ; exit(0) ; } idindex2->next = NULL ; strcpy( idindex2->id , book->id ) ; strcpy( bookindexlist->bookindex[bookindexlist->number].index , lastkeyword->keyword[i] ) ; bookindexlist->bookindex[bookindexlist->number].head->next = idindex2 ; // 第一次插入 bookindexlist->number++ ; } } } // 將兩個索引項交換位置 void SwapIndexItem( BookIndex * bookindex1 , BookIndex * bookindex2 ) { BookIndex tmp ; tmp = *bookindex1 ; *bookindex1 = *bookindex2 ; *bookindex2 = tmp ; } // 將詞索引表中的索引項的關鍵字中的首字母大寫變為小寫 void exchange( BookIndexList * bookindexlist ) { for( int i = 0 ; i < bookindexlist->number ; i++ ) { if( bookindexlist->bookindex[i].index[0] <= 'Z' ) { bookindexlist->bookindex[i].index[0] = char( int(bookindexlist->bookindex[i].index[0] ) + 32 ) ; } } } // 將生成的詞索引表按照字典序進行排序 void SortByKey( BookIndexList * bookindexlist ) { int k = 0 ; for( int i = 0 ; i < bookindexlist->number - 1 ; i++ ) { for( int j = i + 1 ; j < bookindexlist->number ; j++ ) { k = 0 ; // 初始化 while( 1 ) { if( bookindexlist->bookindex[i].index[k] > bookindexlist->bookindex[j].index[k] ) { SwapIndexItem( &bookindexlist->bookindex[i] , &bookindexlist->bookindex[j] ) ; break ; } else if( bookindexlist->bookindex[i].index[k] == bookindexlist->bookindex[j].index[k] ) { k++ ; } else { break ; } } } } } // 建立詞索引表 void CreateIndexList( BookList * booklist , KeyWordList * lastkeyword , BookIndexList * bookindexlist , WordList * wordlist ) { // 遍歷每一個索引項 for( int i = 0 ; i < booklist->number ; i++ ) { HandleOneBookToIndexList( &booklist->book[i] , lastkeyword , bookindexlist , wordlist ) ; } // 將索引項中的關鍵字的首字母大寫變為小寫 exchange( bookindexlist ) ; // 根據索引項關鍵字的首字母進行排序 SortByKey( bookindexlist ) ; printf("生成的詞索引表:\n") ; for( i = 0 ; i < bookindexlist->number ; i++ ) { printf("%s " , bookindexlist->bookindex[i].index ) ; IdIndex * p = bookindexlist->bookindex[i].head->next ; while( p != NULL ) { printf("%s " , p->id ) ; p = p->next ; } printf("\n") ; } }
檔案3:test.cpp
內容:測試
兩個文字檔案,讀寫資料:#include "define.h" void InitSystem( BookList * booklist , WordList *wordlist ) ; void InitBookIndexList( BookIndexList * bookindexlist ) ; void CreateIndexList( BookList * bookist , KeyWordList * lastkeyword , BookIndexList * bookindexlist, WordList * wordlist ) ; int main() { BookList booklist ; WordList wordlist ; KeyWordList lastkeyword ; BookIndexList bookindexlist ; // 詞索引表 InitSystem( &booklist , &wordlist ) ; // 初始化系統 InitBookIndexList( &bookindexlist ) ; // 初始化詞索引表 CreateIndexList( &booklist , &lastkeyword , &bookindexlist , &wordlist ) ; // 建立詞索引表 return 0 ; }
bookinfo.txt
word.txt
執行結果截圖: