使用 Boyer-Moor 算法加速代码

Speeding up code with Boyer-Moor algorithm

提问人:Bonart 提问时间:10/6/2023 最后编辑:kiner_shahBonart 更新时间:10/6/2023 访问量:67

问:

现在我正在尝试制作我的实验室,但由于时间限制,我没有通过测试,所以我需要加快代码执行速度,但不知道如何。因此,对于我的任务,我必须在子行所在的行中输入行数和单词数。这是我的代码

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <fstream>


using namespace std;

int WordCount(const string &s, const int &index) {
    int words = 0;
    for (int i = 0; i < index; i++)
        if (s[i] == ' ')
            words++;
    return words + 1;
}

void toLower(string &s) {
    for (char &c: s)
        c = tolower(c);
}

void removeExtraSpaces(string &input) {
    input.erase(input.begin(), find_if(input.begin(), input.end(), [](const int &ch) {
        return ch != ' ';
    }));
    input.erase(find_if(input.rbegin(), input.rend(), [](const int &ch) {
        return ch != ' ';
    }).base(), input.end());
    auto new_end = std::unique(input.begin(), input.end(), [](const int &left, const int &right) {
        return left == ' ' && right == ' ';
    });
    input.erase(new_end, input.end());
}

void Boyer_Moore(const string &str, const string &substr, vector<int> &result) {

    vector<int> shifts_table(256, substr.size());
    for (int i = substr.size() - 2; i >= 0; i--)
        shifts_table[substr[i]] = std::min(shifts_table[substr[i]], (int) substr.size() - 1 - i);

    int i = substr.size() - 1;
    while (i < str.size()) {
        int j = i;
        int last = i;
        int k = substr.size() - 1;
        while (k >= 0) {
            if (substr[k] == str[j]) {
                k--;
                j--;
            } else {
                i += shifts_table[str[last]];
                break;
            }
        }
        if (k == -1) {
            if ((j < 0 || str[j] == ' ') &&
                (j + substr.size() + 1 >= str.size() || str[j + substr.size() + 1] == ' ')) {
                result.emplace_back(j + 1);
            }
            i += shifts_table[str[last]];
        }
    }
}

int main() {
    ifstream f("input.txt");
    string textLine;
    string line;
    string find_string;
    getline(f, find_string);
    toLower(find_string);
    vector<string> text;
    while (getline(f, line)) {
        removeExtraSpaces(line);
        toLower(line);
        text.emplace_back(line);
        if (!line.empty())
            textLine += std::move(line) + ' ';
    }
    int str_index = 0;
    int start_pos = 0;
    vector<int> result;
    Boyer_Moore(textLine, find_string, result);
    for (const auto &value: result) {
        while (str_index < text.size() && start_pos + text[str_index].size() <= value)
            start_pos += text[str_index].size() + (text[str_index++].empty() ? 0 : 1);
        if (str_index < text.size())
            cout << (str_index + 1) << ", " << WordCount(text[str_index], value - start_pos) << endl;
    }
    return 0;
}

我真的很想在Boyer_Moore功能之后循环加速部分,但我不知道怎么做,有什么想法吗?

这是一个基准: 输入:

cat dog cat dog bird
CAT dog CaT Dog Cat DOG bird CAT
dog cat dog bird

输出:

1, 3
1, 8

如果需要,我会提供更多

C++ 字符串 算法

评论

4赞 MSalters 10/6/2023
无需自己写:std::boyer_moore_searcher
0赞 BoP 10/6/2023
还想知道 Boyer-Moore 是否是此类短字符串的最佳算法。它的表设置成本相当高。
1赞 463035818_is_not_an_ai 10/6/2023
代码到底应该做什么?你的任务是什么?
0赞 Bonart 10/6/2023
我的任务是将文本中的行数和该行中相应子字符串中的单词数放入输出中,我必须使用 Boyer Moore 算法来完成

答: 暂无答案