实验内容及要求:
从键盘输入字符文件名以及子串,用改进KMP算法在字符文件中实现子串查找。要求程序输出子串的改进nextval数组元素值以及子串在文件中成功匹配的次数(查找失败输出成功匹配次数为0)。
实验目的:掌握子串查找的KMP算法。
输入/输出设计简要描述:
输入1:字符文件名,其中储存着主串。且字符文件在程序的同一级目录下。
输入2:模板串
输出1:找到的子串个数
输出2:子串的首字符在主串中的位置(从0开始算起)
#include <iostream>
#include "fstream"
#include "vector"
using namespace std;
void get_next(const string& compare_string, int next[]) {
int i = 0;
int j = 0;
next[0] = -1;
while (++i < compare_string.size()) {
if (compare_string[i] == compare_string[j]) {
next[i] = j++;
while (next[i] != -1 && compare_string[i] == compare_string[next[i]]) {
next[i] = next[next[i]];
}
} else {
next[i] = j;
j = 0;
if (compare_string[i] == compare_string[j]) {
j++;
}
}
}
}
bool improved_kmp(const string& main_string, const string& compare_string, vector<int>& position) {
int next[compare_string.size()];
get_next(compare_string, next);
cout << "nextval: ";
for (int i = 0; i < compare_string.size(); i++) {
cout << next[i] << " ";
}
cout << endl;
int main_position = 0;
int sub_position = 0;
int main_size = main_string.size();
int sub_size = compare_string.size();
while (main_position + sub_size < main_size) {
while (main_position < main_size && sub_position < sub_size) {
if (sub_position == -1 || main_string[main_position] == compare_string[sub_position]) {
main_position++;
sub_position++;
} else {
sub_position = next[sub_position];
}
}
if (sub_position < compare_string.size()) {
continue;
} else {
position.push_back(main_position - sub_position);
sub_position = 0;
main_position++;
}
}
if (position.empty()) {
return false;
} else {
return true;
}
}
int main() {
string file_name;
cout << "Please enter the name of the file:" << endl;
cin >> file_name;
fstream file("../" + file_name);
if (!file.is_open()) {
cout << "File name wrong!" << endl;
}
string main_string;
string compare_string;
vector<int> position;
cout << "Please enter the string you are looking for:" << endl;
cin >> compare_string;
if (compare_string.empty()) {
cout << "Empty string!" << endl;
return 0;
}
file >> main_string;
if (!improved_kmp(main_string, compare_string, position)) {
cout << "Not found!" << endl;
return 0;
}
cout << "There are " << position.size() << " substring totally." << endl;
cout << "position:";
for (auto &i : position) {
cout << i << ", ";
}
cout << endl;
return 0;
}
注意:由于个人电脑问题,路径有可能会出错,请根据情况修改为 “./” 或者 "../"
文章评论