日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

题目3:文本文件单词的检索与计数(实验准备)

發(fā)布時間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 题目3:文本文件单词的检索与计数(实验准备) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

數(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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。