您的位置:首页 > 理论基础 > 数据结构算法

(字符)串

2014-11-11 13:13 211 查看
感觉函数实现比较臃肿,我是按照严书串的定义写的,内容也参考了严书。

/* Author : Moyiii
* Mail: lc09@vip.qq.com
* (字符)串的实现,许多函数感觉是咸的有些麻烦,
* 而且花括号空格占了很大空间,因此显得代码很臃肿
* 希望有更好的更简单的方法,能够告诉我~谢啦
* 仅作学习之用,当然如果你想拿去用,随你好啦。
* 如果发现BUG,或你有更好的想法,欢迎反馈给我
*/

#include <iostream>
using namespace std;

//ADT采用严书串的定义
class DString
{
public:
bool strAssign(const char *chars);
int getLength();
static int comp(DString &a, DString &b);
void clear();
static bool concat(DString &dest, DString &a, DString &b);
bool sub(DString &dest, int pos, int len);
int index(DString &str, int pos);
int kmp(DString &str, int pos);
void print();

private:
char *ch;
int length;
void getNext(char *str, int len, int *next);
};

//我承认我是看着严蔚敏的书写的这个函数
bool DString :: strAssign(const char *chars)
{
if( !ch )
{
delete []ch;
}

int len = 0;
while(chars[len])
{
len++;
}
if(len == 0)
{
length = 0;
ch = NULL;
}
else
{
ch = new char[len];
if ( !ch )
{
cout << "Malloc error!" << endl;
return false;
}
for(int i = 0; i < len; ++i)
{
ch[i] = chars[i];
}
length = len;
}
return true;
}

void DString :: print()
{
for(int i = 0; i < length; ++i)
{
cout.put(ch[i]);
}
cout << endl;
}

int DString :: getLength()
{
return length;
}

//比较两个数大小,从头比到尾,一旦不相等,则可知道
//第一个不相等字符较小的字符串值比较小,若某个字符串
//是另一个的字串,则长度短的字符串值较小
int DString :: comp(DString &a, DString &b)
{
for(int i = 0; i != a.length && i != b.length; ++i)
{
if(a.ch[i] != b.ch[i])
{
return (a.ch[i] - b.ch[i]);
}

}
return (a.length - b.length);
}

void DString :: clear()
{
if( !ch )
{
delete []ch;
ch = NULL;
}
length = 0;
}

//为了防止dest 和 a或者b是同一个,因此在函数内定义了一个临时
//变量用来保存连接后的字符串
bool DString :: concat(DString &dest, DString &a, DString &b)
{
int tLen = a.length + b.length;
char *temp = new char[tLen];
for(int i = 0; i < a.length; ++i)
{
temp[i] = a.ch[i];
}
for(int j = 0; j < b.length; ++j)
{
temp[j+a.length] = b.ch[j];
}

if( dest.ch )
{
delete []dest.ch;
dest.ch = NULL;
}

dest.ch = new char[tLen];
if(!dest.ch)
{
cout << "OverFlow" << endl;
return false;
}

for(int i = 0; i < tLen; ++i)
{
dest.ch[i] = temp[i];
}
dest.length = tLen;

delete []temp;

return true;
}

//注意截断处理
bool DString :: sub(DString &dest, int pos, int len)
{
if(pos >= length || len < 0)
{
cout << "Arguments Error" << endl;
return false;
}

int tLen = len;
//最多截取到字符串结尾
if(pos + len > length)
{
tLen = length - pos;
}

char *tchar = new char[tLen];
for(int i = 0; i < tLen; ++i)
{
tchar[i] = ch[pos+i];
}
//清除原来的信息
if( dest.ch )
{
delete []dest.ch;
dest.ch = NULL;
}

if(tLen = 0)
{
dest.length = 0;
return true;
}

dest.ch = new char[tLen];
if(!dest.ch)
{
cout << "OverFlow" << endl;
return false;
}

for(int i = 0; i < tLen; ++i)
{
dest.ch[i] = tchar[i];
}
dest.length = tLen;

delete []tchar;

return true;
}

//str非空,严书P79,无回退暴力比较法
int DString :: index(DString &str, int pos)
{
int i = pos ,j = 0;
while( i != length && j != str.length)
{
if(ch[i] == str.ch[j])
{
i++;
j++;
}
else
{
i = i - j + 1;
j = 0;
}
}
if(j >= str.length)
{
return (i - j);
}
else
{
return -1;
}
}

void DString :: getNext(char *str ,int len, int *next)
{
int i = 0;
int j = -1;
next[0] = -1;
while(i < len)
{
if(j == -1 || str[i] == str[j])
{
i++;
j++;
if(str[i] == str[j])
{
next[i] = next[j];
}
else
{
next[i] = j;
}
}
else
{
j = next[j];
}
}
return;
}

//KMP算法,我是扛不住了。你自己去看书,这个我也晕
int DString :: kmp(DString &str, int pos)
{
int i = pos, j = 0;
int *next = new int[str.length];
getNext(str.ch, str.length ,next);
while(i < length && j < str.length)
{
if(ch[i] == str.ch[j])
{
++i;
++j;
}
else
{
j = next[j];
if(j == -1)
{
j = 0;
i++;
}
}
}
if(j >= str.length)
{
return (i - j);
}
else
{
return -1;
}
}

int main()
{
DString a;
a.strAssign("Hello,World,ello!");
a.print();
DString b;
b.strAssign("ello");
b.print();
int pos = a.kmp(b, 2);
cout << pos << endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 字符串