(字符)串
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;
}
/* 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;
}
相关文章推荐
- ERROR: RCMake failed: 路径中具有非法字符
- 界面资料 用的是内部数子外部字符显示,计算时还是用数字因为数字不字符快
- TextOutA(),TextOutW(),TextOut()的区别?+宽字符问题
- poi数据导出时纯数字字段被以字符形式生成到excel中
- IOS 开发中判断NSString是否为空字符
- 字符全排列、全组合以及相关问题
- I do. 【附:C++用不多于一条推博字符数的代码能作出怎样的图像?】
- 找字符串中出现最对的字符,并统计个数,个人方案仅供参考
- 字符排序
- java 输入一个字符串,打印出该字符串中字符的所有排列
- Python3基础 dic in/not in 查询一个字符是否指定字典的键或者值
- Linux下文件操作,打开一个文件并修改文件后5个字符为abcde
- http 请求数据返回 json 中中文字符为 unicode 编码转汉字转码
- 常用的“稀有”字符 (来自Gucharmap)
- [Java] FileReader/FileWriter 字符流
- EXCEL导入到SQL Server经常出现“文本被截断,或者一个或多个字符在目标代码页中没有匹配项”错误的解决
- C++字符数组越界问题的一个案例分析
- 为什么字符串在Java中是不可变的?
- 字符数组和字符串的区别
- [C语言] 对于scanf()函数使用%d格式说明符无法读取字符的个人理解