#include <iostream> #include <algorithm> #include <vector> #include <string> using namespace std; bool KMP(const string &s1, const string &s2); vector<int> findMatchInFrontAndBack(const string &s2); int partPi(const string &amatch); int main() { cout << "这个程序能够判断s1内是否包含s2" << endl; string s1, s2; cout << "请输入字符串1" << endl; cin >> s1; cout << "请输入字符串2" << endl; cin >> s2; KMP(s1, s2); return 0; } bool KMP(const string &s1, const string &s2) { if (s2.size()>s1.size()) { cout << "字符串1里面不包含字符串2" << endl; return false; } else { vector<int> nodes = findMatchInFrontAndBack(s2); int histroySite = 0; while (s1.size() - s2.size() >= histroySite) { int matchNum = 0; bool allOverMatch = true; for (int i = 0;i<s2.size();++i) { if (s1[histroySite + i] != s2[i]) { allOverMatch = false; if (matchNum == 0) { ++histroySite; } else { histroySite += (matchNum - nodes[i]); } break; } else { ++matchNum; } } if (allOverMatch) { cout << "s1中包含s2" << endl; cout << s1 << endl; for (int i = 0;i<histroySite;++i) { cout << " "; } cout << s2 << endl; return true; } } cout << "字符串1里面不包含字符串2" << endl; return false; } } vector<int> findMatchInFrontAndBack(const string &s2) { if (s2.size() == 1) { vector<int> nodeOfMatch = { 0 }; return nodeOfMatch; } else { vector<int> nodeOfMatch(s2.size() - 1, 0); auto be = s2.begin(); auto en = be + 2; for (int i = 1;i<s2.size() - 1;++i) { string amatch; amatch.insert(amatch.end(), be, en); nodeOfMatch[i] = partPi(amatch); ++en; } nodeOfMatch.push_back(0); return nodeOfMatch; } } int partPi(const string &amatch) { vector<string> frontOfString; vector<string> backOfString; auto startOne = amatch.begin(); auto nextOne = startOne + 1; for (int i = 0;i<amatch.size() - 1;++i) { string fs, bs; fs.insert(fs.end(), startOne, nextOne); bs.insert(bs.end(), nextOne, amatch.end()); frontOfString.push_back(fs); backOfString.push_back(bs); ++nextOne; } sort(frontOfString.begin(), frontOfString.end()); sort(backOfString.begin(), backOfString.end()); int highestNum = 0; while (frontOfString.size() != 0 && backOfString.size() != 0) { auto s1 = frontOfString.begin(); auto s2 = backOfString.begin(); if (*s1 == *s2) { if (s1->size()>highestNum) { highestNum = s1->size(); } frontOfString.erase(s1); backOfString.erase(s2); } else if (*s1<*s2) { frontOfString.erase(s1); } else { backOfString.erase(s2); } } return highestNum; }