其中kmp算法的思想理解了,但是这段kmp算法求next数组的代码理解不是很透彻,希望有人能详细讲解一下 //MyString.h #ifndef MYSTRING_H #define MYSTRING_H #include <iostream> using namespace std; class MyString { public: MyString(); //默认构造函数 MyString(const char* rhs); //接收字符串常量的构造函数 MyString(const MyString& rhs); //复制构造函数 ~MyString(); //析构函数 MyString& operator=(const MyString& rhs); //赋值操作符 char& operator[](const size_t index); //下标操作符 const char& operator[](const size_t index) const; //常量版下标操作符 MyString GetSubString(const size_t index,int len); //返回index位序开始长度为len的子串 inline size_t GetLength() //返回字符串长度 { return length; } int Index(const MyString& m,int pos); //从pos位置开始查找字符串m,并返回他的位置,如果没有找到则返回0 friend MyString operator+(const MyString& lhs, const MyString& rhs); //连接两个字符串 friend bool operator==(const MyString& lhs, const MyString& rhs); //比较两个字符串是否相等 friend bool operator!=(const MyString& lhs, const MyString& rhs); //比较两个字符串是否不等 friend bool operator<(const MyString& lhs, const MyString& rhs); //左操作数是否小于右操作数 friend bool operator>(const MyString& lhs, const MyString& rhs); //左操作数是否大于右操作数 friend ostream& operator<<(ostream& os,const MyString& rhs); //输出操作符 private: void get_next(const MyString& T,int next[]); //求模式串的next数组 char* str; //字符串首地址 int length; //字符串长度 }; #endif //MyString.cpp #include <iostream> #include "MyString.h" using namespace std; MyString::MyString() { str=new char('/0'); length=0; } MyString::MyString(const char* rhs) { length=strlen(rhs); str=new char[length+1]; for(int i=0;i<length;i++) { str[i]=rhs[i]; } str[length]='/0'; } MyString::MyString(const MyString& rhs) { length=rhs.length; str=new char[length+1]; for(int i=0;i<length;i++) { str[i]=rhs.str[i]; } str[length]='/0'; } MyString::~MyString() { delete str; } MyString& MyString::operator = (const MyString& rhs) { if(this==&rhs) return *this; length=rhs.length; str=new char[rhs.length+1]; for(int i=0;i<length;i++) { str[i]=rhs.str[i]; } str[length]='/0'; return *this; } char& MyString::operator [] (const size_t index) { return str[index]; } const char& MyString::operator [] (const size_t index) const { return str[index]; } MyString MyString::GetSubString(const size_t index,int len) { MyString ret; if(len<1 || len>length-index+1) //判断len值是否合法 { cerr<<"len值不合法"<<endl; return ret; } ret.str=new char[len+1]; ret.length=len; for(int i=0;i<len;i++) { ret.str[i]=str[index-1+i]; } ret.str[ret.length]='/0'; return ret; } /*int MyString::Index(const MyString& m,int pos) { int i=pos-1; int j=0; while(i<length && j<m.length) { if(str[i] == m.str[j]) { i++; j++; } else { i=i-j+1; j=0; } } if(j==m.length) //比较成功 { return i-j+1; } return 0; }*/ void MyString::get_next(const MyString& T,int next[]) // 求模式串T的next函数值并存入数组 next。 { int j=0, k=-1; next[0]=-1; while ( T[j]!='/0' ) { if (k==-1 || T[j]==T[k]) { ++j; ++k; if (T[j]!=T[k]) next[j]=k; else next[j]=next[k]; } else k=next[k]; } } int MyString::Index(const MyString& m,int pos) //KMP算法 { int i=pos; int k=-1; int* pnext=new int[m.length+1]; get_next(m,pnext); while(i<length && k<m.length) { if(k==-1 || str[i]==m.str[k]) { ++i; ++k; } else { k=pnext[k]; } } if(k==m.length) { delete []pnext; return i-k+1; } delete []pnext; return 0; } MyString operator+(const MyString& lhs, const MyString& rhs) //连接两个字符串 { MyString ret; ret.length=lhs.length+rhs.length; ret.str=new char[ret.length+1]; for(int i=0;i<lhs.length;i++) //复制第一个串 { ret.str[i]=lhs.str[i]; } for(int j=0;j<rhs.length;j++) //复制第二个串 { ret.str[lhs.length+j]=rhs.str[j]; } ret.str[ret.length]='/0'; return ret; } bool operator==(const MyString& lhs, const MyString& rhs) //比较两个字符串是否相等 { if(lhs.length != rhs.length) return false; for(int i=0;i<lhs.length;i++) { if(lhs[i] != rhs[i]) return false; } return true; } bool operator!=(const MyString& lhs, const MyString& rhs) //比较两个字符串是否不等 { return !(lhs==rhs); } bool operator<(const MyString& lhs, const MyString& rhs) //左操作数是否小于右操作数 { if(lhs==rhs) return false; else { for(int i=0;i<lhs.length && i<rhs.length;i++) { if(lhs[i] < rhs[i]) return true; else if(lhs[i] > rhs[i]) return false; } } if(lhs.length < rhs.length) return true; else return false; } bool operator>(const MyString& lhs, const MyString& rhs) //左操作数是否大于右操作数 { if(lhs == rhs || lhs < rhs) return false; return true; } ostream& operator<<(ostream& os,const MyString& rhs) //输出操作符 { for(int i=0;i<rhs.length;i++) os<<rhs.str[i]; return os; } //test.cpp #include <iostream> #include "MyString.h" using namespace std; int main() { MyString str; MyString str1("asdju3ehiodssdfo324329asdkj"); MyString str2(str1); str=str1+str2; str1="f"; //cout<<"str:"<<str<<endl; // cout<<"str1:"<<str1<<endl; cout<<"str2:"<<str2<<endl; // cout<<str2.GetSubString(5,3)<<endl; //cout<<str2.GetLength(); int pos=0; if(pos=str2.Index("ssdf",1)) cout<<"找到了,位置在:"<<pos<<endl; else cout<<"没找到"<<endl; // if(str2<str1) // cout<<"小于"<<endl; // else // cout<<"不小于"<<endl; return 0; }