题目3:文本文件单词的检索与计数(实验准备)
數(shù)據(jù)結(jié)構(gòu)課程實踐系列
題目1:學(xué)生成績檔案管理系統(tǒng)(實驗準(zhǔn)備)
題目2:隱式圖的搜索問題(A*算法解決八數(shù)碼)
題目3:文本文件單詞的檢索與計數(shù)(實驗準(zhǔn)備)
文章目錄
- 數(shù)據(jù)結(jié)構(gòu)課程實踐系列
- 題目1:學(xué)生成績檔案管理系統(tǒng)(實驗準(zhǔn)備)
- 題目2:隱式圖的搜索問題(A*算法解決八數(shù)碼)
- 題目3:文本文件單詞的檢索與計數(shù)(實驗準(zhǔn)備)
- 聲明
- 實驗任務(wù)
- 實驗要求
- 所需知識
- 導(dǎo)出所需知識
- API對文本文件的讀取
- KMP算法的詳解
- NEXT數(shù)組具體過程
- 1號位(注意,以下講解中,指針是不移動的,只有字符串在移動)
- 2號位
- 3號位
- 4號位
- 5號位
- 6號位
- 總結(jié):
- 實現(xiàn)代碼
聲明
實驗任務(wù)
- 建立一個文本文件,統(tǒng)計給定單詞在文本文件中出現(xiàn)的總次數(shù)及位置;
實驗要求
- 文本文件中每個單詞不包含空格且不跨行,單詞由字符序列構(gòu)成且區(qū)分大小寫,統(tǒng)計給定單詞在文本文件中出現(xiàn)的總次數(shù),檢索輸出的某個單詞出現(xiàn)在文本中的行號、在該行中出現(xiàn)的位置
- 設(shè)計數(shù)據(jù)量大的文本,進(jìn)行子串的查詢處理,分析算法運行的時間效率,對所有輸出的匹配位置結(jié)果進(jìn)行驗證,以證明算法設(shè)計和實現(xiàn)的正確性。
- 用樸素模式匹配算法或KMP算法實現(xiàn)字符串定位;
- 可正確讀取,保存文本;
所需知識
IO流文件讀取(或者API對文本文件的讀取也行),外加KMP算法的實現(xiàn)
導(dǎo)出所需知識
API對文本文件的讀取
一個ReadFileAPI即可解決,至于它的詳細(xì)用法,我已在核心編程模塊中用過,并且做下筆記,如下超鏈接:
ReadFile API的介紹外加實際操作
KMP算法的詳解
這個算法我也已經(jīng)在博客中進(jìn)行實際的講述并且記錄(畢竟KMP算法還是得分情況,種類挺多的,得需要幾萬字講述,這里就不一一講述):
徹底理解KMP,其實最主要的也就是理解NEXT數(shù)組,只要找到前綴后綴最長公共元素長度,然后構(gòu)成NEXT數(shù)組,緊接著就是利用NEXT數(shù)組來進(jìn)行相應(yīng)跳轉(zhuǎn)比較即可
NEXT數(shù)組具體過程
直接移動模式串,使得公共前后綴的前綴直接移動到了后綴所在的位置
再求next數(shù)組時只需要看模式串即可,模式串中對應(yīng)的位置與主串不匹配時,找出對應(yīng)位置之前的串中的公共前后綴(找最長的公共前后綴,且要小于對應(yīng)位置之前的串長度),然后往前移動前后串。(一般我們的字符串都存在一個字符數(shù)組中,數(shù)組在內(nèi)存中是不可能移動的,所以移動這說法只是一個形象化過程,要把它轉(zhuǎn)化為下面這種處理方式)
1號位(注意,以下講解中,指針是不移動的,只有字符串在移動)
假設(shè)模式串存在一個以下標(biāo)為1開始的數(shù)組中,而且假設(shè)這個字符串會與任何一個字符串去比較(進(jìn)行KMP算法),那么任何一個位置都可能不匹配,如下圖
那么接下來只需要把模式串前移一位,(也就是說把模式串中1號下標(biāo)的字符與主串下一個下標(biāo)的字符進(jìn)行比較)
處理方法:1號位與主串下一位比較
2號位
假如2號位不匹配呢?如下圖
提醒:主串中第一個是A,打錯了
那么接下來該怎么移動呢?這里的公共前后綴為0,所以的話,只需要進(jìn)行如下操作(移動后,指針左邊的長度就是公共前后綴的長度)
處理方法:1號位與主串當(dāng)前位置比較
3號位
那么這下直接看模式串嘍,最長公共前后綴為0,所以處理方法和2號位一樣哦
處理方法:1號位與主串當(dāng)前位置比較
4號位
最長公共前后綴為1,
也就是要如下移動操作
處理方法:2號位與主串當(dāng)前位置比較
5號位
最長公共前后綴為2,
也就是要如下移動操作
6號位
最長公共前后綴為2,
也就是要如下移動操作
也就是4號位于當(dāng)前主串進(jìn)行比較(總結(jié):每次開始比較的編號=最大公共前后綴長度+1)
總結(jié):
每次開始比較的編號=最大公共前后綴長度+1(除了第一句話,也就是0)
轉(zhuǎn)化為數(shù)組之后,如下:
然后放在一個數(shù)組中,
實現(xiàn)代碼
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<Windows.h> #define BUF_SIZE 256 typedef struct seqstring {char string[100];int length; }seqstring;void getnext(seqstring p, int next[]) {int i, j;i = 0;//指向字符串每個字符的下標(biāo)j = -1;next[i] = j;//next[0]放上-1 while (i < p.length) {//沒有到達(dá)結(jié)尾的話 if (j == -1 || p.string[i] == p.string[j]) {//如果是第一個字符或遇到相同的字符next[++i] = ++j;}else {j = next[j];}}for (i = 0;i < p.length;i++) {//輸出next[]值 printf("%d ", next[i]);} }int kmp(seqstring t, seqstring p, int next[]) {int i, j;i = j = 0;while (i < t.length && j < p.length) {if (j == -1 || t.string[i] == p.string[j]) {i++;j++;}else {j = next[j];}}if (j == p.length) return i - p.length;else return -1; } int main() {seqstring t, p;int next[50];DWORD nIn;char buffer[BUF_SIZE] = "";HANDLE handle = CreateFile("test.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if (handle == INVALID_HANDLE_VALUE) {printf("%d", GetLastError());return -1;}ReadFile(handle, buffer, BUF_SIZE, &nIn, NULL) ;strcpy(t.string, buffer);printf("%s\n", t.string);t.length = strlen(t.string);printf("please input string p:");scanf("%s", p.string);printf("%s\n", p.string);p.length = strlen(p.string);printf("next:");getnext(p, next);printf("\n%d\n", kmp(t, p, next)); }
基本功能實現(xiàn)了,接下來也就差點添油加醋嘍,隨便改改就行了
總結(jié)
以上是生活随笔為你收集整理的题目3:文本文件单词的检索与计数(实验准备)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 题目1:学生成绩档案管理系统(实验准备)
- 下一篇: 题目1:学生成绩档案管理系统(代码实现)