您的位置:首页 > 其它

KMP字符串匹配

2015-11-26 19:27 344 查看
#ifndef _MSTRING_H
#define _MSTRING_H

#include<iostream>
#include<string.h>
using namespace std;

#define MSTRING_ERROR 1
#define MSTRING_NORMAL 0

class MString
{
public:
MString();
MString(char *str);
~MString();
void println();
int get_lenth();
MString &operator=(char *str); //等号赋值
MString &operator=(MString T);
void add_tail(const char *str); //向尾部连接字符串
void add_tail(MString mstr);
void add_ahead(const char *str); //向头部连接字符串
void add_ahead(MString mstr);
int find_first_of(const char *str); //查找第一个匹配字符串位置
int find_first_of(MString mstr);
int find_all_of(const char *str,int *out,int maxnum); //找到所有匹配字符串位置,最大数目maxnum,返回个数,out数组
int find_all_of(MString mstr, int *out, int maxnum);
char* get_char(); //返回字符指针,原指针非复制,因此谨慎赋值
int replace_all(const char *straim, const char *strtar); //替换全部straim字符串为strtar
int replace_all(MString mstraim, MString mstrtar);
int cmp(const char *str); //比较大小
int cmp(MString mstr);

private:
void get_next(const char *T, int *next);
int kmp(const char *S,const char *T, int pos);
private:
char *ch;
int lenth;
};

MString::MString()
{
lenth = 0;
ch = NULL;
}

MString::MString(char *str)
{
lenth = strlen(str);
ch = new char[lenth+1];
strcpy(ch, str);
}

MString::~MString()
{
if (ch != NULL)
{
delete[] ch;
}
}

void MString::println()
{
printf("%s\n", ch);
}

int MString::get_lenth()
{
return lenth;
}

inline MString & MString::operator=(char * str)
{
if (ch != NULL)
{
delete[] ch;
}
lenth = strlen(str);
ch = new char[lenth+1];
strcpy(ch, str);
return *this;
}

inline MString & MString::operator=(MString T)
{
if (ch != NULL)
{
delete[] ch;
}
lenth = T.lenth;
ch = new char[lenth + 1];
strcpy(ch, T.ch);
return *this;
}

void MString::add_tail(const char * str)
{
char *tmpstr;
int len, i, g;
tmpstr = new char[lenth+1];
strcpy(tmpstr, ch);
if (ch != NULL)
{
delete[] ch;
}
len = strlen(str);
ch = new char[len + lenth + 1];
g = 0;
for (i = 0;i < lenth;i++)
{
ch[g++] = tmpstr[i];
}
for (i = 0;i < len;i++)
{
ch[g++] = str[i];
}
ch[g] = '\0';
lenth = len + lenth;
delete[] tmpstr;
}

inline void MString::add_tail(MString mstr)
{
add_tail(mstr.ch);
}

void MString::add_ahead(const char *str)
{
char *tmpstr;
int len, i, g;
tmpstr = new char[lenth + 1];
strcpy(tmpstr, ch);
if (ch != NULL)
{
delete[] ch;
}
len = strlen(str);
ch = new char[len + lenth + 1];
g = 0;
for (i = 0;i < len;i++)
{
ch[g++] = str[i];
}
for (i = 0;i < lenth;i++)
{
ch[g++] = tmpstr[i];
}
ch[g] = '\0';
lenth = len + lenth;
delete[] tmpstr;
}

inline void MString::add_ahead(MString mstr)
{
add_ahead(mstr.ch);
}

void MString::get_next(const char *T, int *next)
{
char *tmpstr;
int len;
len = strlen(T);
tmpstr = new char[len + 2];
strcpy(tmpstr + 1, T);
tmpstr[0] = '\0';
int i, j;
i = 1;next[1] = 0;j = 0;
while (i<len)
{
if (j == 0 || tmpstr[i] == tmpstr[j])
{
++i;++j;
if (tmpstr[i] != tmpstr[j]) next[i] = j;
else next[i] = next[j];
}
else j = next[j];
}
delete[] tmpstr;
}

//返回第一个T出现在S处的下标,pos设定从哪个下标开始向后找
int MString::kmp(const char *S,const char *T, int pos)
{
int i, j, lens, lent, k;
int *next;
i = pos;j = 0;
lens = strlen(S);
lent = strlen(T);
next = new int[lent + 1];
get_next(T, next);
k = 0;
while (i<lens&&j<lent)
{
if (S[i] == T[j])
{
i++;
j++;
}
else
{
j = next[j + 1] - 1;
if (j == -1)
{
i++;
j++;
}
}
}
delete[] next;
if (j >= lent) return i - lent;
else return -1;
}

/*
搜索查找第一个匹配字符的位置,查找算法:KMP
*/
int MString::find_first_of(const char *str)
{
if (ch == NULL) return -1;
return kmp(ch,str,0);
}

inline int MString::find_first_of(MString mstr)
{
return find_first_of(mstr.ch);
}

int MString::find_all_of(const char *str,int *out,int maxnum)
{
if (ch == NULL) return -1;
if (maxnum < 1) return -1;
int i,j,len,num;
len = strlen(str);
i = 0;
j = 0;
num = 0;
while (1)
{
out[i] = kmp(ch, str, j);
if (out[i] == -1) return i;
j = len+ out[i];
i++;
if (i >= maxnum) return maxnum;
}
}

inline int MString::find_all_of(MString mstr, int * out, int maxnum)
{
return find_all_of(mstr.ch, out, maxnum);
}

inline char * MString::get_char()
{
return ch;
}

int MString::replace_all(const char *straim, const char *strtar)
{
int i, j, num, lena, lent, lenc;
j = 0;
num = 0;
lena = strlen(straim);
lent = strlen(strtar);
lenc = strlen(ch);
while (1)
{
i = kmp(ch, straim, j);
if (i == -1) break;
num++;
j = i + lena;
}
int *ta;
ta = new int[num];
j = 0;
i = 0;
for (i = 0;i < num;i++)
{
ta[i] = kmp(ch, straim, j);
j = ta[i] + lena;
}
char *distr;
int lendi;
lendi = lenc - lena*num + lent*num + 1;
distr = new char[lendi];
i = 0;
int g = 0;
int k = 0;
while (i<lendi-1)
{
if (k != ta[g])
{
distr[i++] = ch[k++];
}
else
{
for (j = 0;j < lent;j++)
{
distr[i++] = strtar[j];
}
g++;
k += lena;
}
}
distr[lendi - 1] = '\0';
lenth = lendi - 1;
delete[] ta;
if (ch != NULL) delete[] ch;
ch = distr;
return num;
}

inline int MString::replace_all(MString mstraim, MString mstrtar)
{
return replace_all(mstraim.ch, mstrtar.ch);
}

inline int MString::cmp(const char * str)
{
return strcmp(ch, str);
}

inline int MString::cmp(MString mstr)
{
return strcmp(ch, mstr.ch);
}

#endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: