文學研究助手的實現
設計目的:
1. 熟悉串類型的實現方法和文本匹配方法。
2. 熟悉一般文字處理軟件的設計方法。
設計內容:
文學研究人員需要統計某篇英文小說中某些形容詞的出現次數和位置。試寫一個實現這
一目標的文字統計系統,稱為“文學研究助手”。
設計要求:
1. 英文小說存於一個文本文件中。
2. 待統計的詞匯集合要一次輸入完畢。
3. 程序的輸出結果是每個詞的出現次數和出現位置所在行的行號,格式
自行設計。
源代碼
#include<iostream>
#include<cstdlib>
#include<fstream>
using namespace std;
char *FileRead(char ch[]) //讀文件函數
{
char *c = (char *)calloc(2000, sizeof(char)); //calloc分配出來的內存,返回值也是void * 但是分配的內存是被清空過的,更安全
int i = 0;
ifstream in(ch);
if (!in) { cout << "不能打開文件" << ch << endl; return 0; }
in >> noskipws; //讀文件不跳過空格
while (!in.eof()) //eof 判斷是否讀到文件尾
{
in >> c[i++];
}
in.close();
return c;
}
void GetNext(char t[], int next[])
{// 求模式串T的next函數值並存入數組next
int j = 0, k = -1;
int n = strlen(t);
next[j] = -1;
while (j<n)
{
if (k == -1 || t[j] == t[k])
{
j++; k++; next[j] = k;
}
else k = next[k];
}
}
int IndexKMP(char s[], char t[], int next[])
{// 利用模式串T的next函數求T在主串S中第pos個字符之後的位置的KMP算法。
// 其中,T非空,1≤pos≤StrLength(S)
int i, j;
i =0; j = 0;
int count = 0; //計數器
int m = strlen(s), n = strlen(t);
while (i<m && j<n) //
{
if (j == -1 || s[i] == t[j])
{
i++; j++;
} // 繼續比較後繼字符
else j = next[j];// 模式串向右移動
if (j >= n)
{
count++;
cout << "單詞第"<<count<<"次出現在" << (i - j + 1) / 84 + 1 << "行,第" << (i - j + 1) << "個字符開始" << endl;
j = 0; //J必須重新賦值為零,
}// 匹配成功
}
return count;
}
void ShowMenu()
{
cout << "********************************************" << endl;
cout << "****** 文 學 研 究 助 手 ******" << endl;
cout << "****** 0.安全退出系統 ******" << endl;
cout << "****** 1.文件讀入小說 ******" << endl;
cout << "****** 2.輸出小說文本 ******" << endl;
cout << "****** 3.查詢小說關鍵字 ******" << endl;
cout << "\n\t\n\t\t請選擇:";
}
int main()
{
char index[10] = { 0 }, novel_path[10] = { 0 }; //賦初值為零,分配內存時初始化為零,
char *ch;
int *next, index_length, n, x = 100;
cout << "\t\t\t登陸文學研究助手...\n\n\n"<< endl;
while (x != 0)
{
system("pause");
system("cls"); //清屏
ShowMenu();
cin >> x;
switch (x)
{
case 0:
exit(0);
break;
case 1:
cout << "請輸入小說文件路徑:";
cin >> novel_path;
ch = FileRead(novel_path);
cout << "文件讀入成功!" << endl;
break;
case 2:
cout << ch << endl;
break;
case 3:
{
cout << ch << endl;
cout << "請輸入要查詢的單詞:";
getchar();
cin.get(index, 20);
index_length = strlen(index);
next = new int[index_length];
GetNext(index, next);
n = IndexKMP(ch, index, next);
cout << index << "在小說中總共出現" << n << "次" << endl;
}
break;
default:
break;
}
}
system("pause");
return 0;
}