西南交通大学数据结构第四次实验报告--基于改进KMP算法的字符文件子串查找

实验内容及要求:

从键盘输入字符文件名以及子串,用改进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;
}

注意:由于个人电脑问题,路径有可能会出错,请根据情况修改为 “./” 或者 "../"

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jellyfish Knight

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值