【算法与数据结构】KMP算法

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/aoumeior/article/details/78556853

Kmp由于其超低的时间复杂度O(m+n),因而被应用到广泛的应用到各种编辑器上。作为基础算法,网上有太多的人孜孜不倦的写教程,所以具体思想也就不再赘述。

看来有些程序员为了造轮子,解释思想,真是不择手段。

具体思想可以看这篇文章:
KMP算法详解

Kmp算法排除思想外,很值得说的就是由于其不回溯的特性,其适用于大型匹配。

#include<iostream>
#include<string>

#define DEBUG

#ifdef DEBUG

#include<vector>

#endif // DEBUG

class Kmp {

public:

    Kmp(const std::string& str) 
        :substr{ str }, next{ new int[str.length()+1]{} } {

        getnext(substr,next);
    }

    ~Kmp(){

        if (next != nullptr) {
            delete[] next;
        }
    }

    int capture(std::string str) {

#ifdef DEBUG
        std::vector<char> all;;
#endif // DEBUG 

        const auto subLength = substr.length();
        const auto strLength = str.length();
        size_t i = 0, j = 0;
        while (j == -1 || i < strLength  && j < subLength) {

            if ( str[i] == substr[j] ) {

#ifdef DEBUG
                all.push_back(str[i]);
                letterVector.push_back(str[i]);
#endif // DEBUG     

                    i += 1;
                    j += 1;
            }
            else {

                j = next[j];

                if (j == -1) { i++; j++;}

#ifdef DEBUG

                all.push_back(str[i]);
                auto beDele = letterVector.begin() + letterVector.size() - j;
                letterVector.erase(letterVector.begin(), beDele);
#endif // DEBUG

            }
        }

        if ( j < subLength) {

            return i - subLength;
        }

#ifdef DEBUG
        std::cout << all.size() << std::endl;
        std::cout << "The last matching sequences :" << std::endl;
        for (auto letter : letterVector) {

            std::cout << letter << "  ";
        }
#endif // DEBUG

        return 0;
    }

private:

    void getnext(const std::string& subStr, int  next[]) {

        next[0] = -1;
        int j = -1;
        size_t i = 0;
        while (i < subStr.length()){

            if (j == -1 || subStr[i] == subStr[j]) {

                /*j++;
                i++;
                next[i] = j;*/

                if (subStr[++i] == subStr[++j]) {

                    next[i] = next[j];
                }
                else {

                    next[i] = j;
                }
            }
            else{

                j = next[j];
            }
        }

#ifdef DEBUG

        std::cout << "next sequnences:";
        for (auto i = 0; i < substr.length(); i++) {

            std::cout << next[i] <<" ";
        }
        std::cout << std::endl;
#endif // DEBUG

    }

private:

    std::string substr;
    int *next;

#ifdef DEBUG

    std::vector<char> letterVector;

#endif // DEBUG
};


int main() {
    auto sequece = "ABCDABABCDABXBABCDABABCDABB";
    Kmp check{ "ABABAAB" };
    std::cout<<check.capture(sequece);
    return 0;
}
展开阅读全文

没有更多推荐了,返回首页