C++自定义字符串类
//header.h
#ifndef _HEADER_H
#define _HEADER_H
#define defaultSize 128
#include<iostream>
#include<assert.h>
#include<string.h>
using namespace std;
class myString
{
private:
char *ch;
int curLength;
int maxSize;
protected:
friendostream& operator<<(ostream& out, myString& str)
{
if(str.curLength>0 && str!=NULL)
cout<<str.ch<<endl;
else
cerr<<"error string object!\n";
return out;
}
public:
myString(int sz=defaultSize);//三种构造方式
myString(const char *init);
myString(const myString& ob);
~myString(){delete []ch;}
void print();//打印字符串
int Length()const;
myString operator()(int pos, int len);//字符串切片操作
bool operator == (myString& ob)const;//符号重载
bool operator != (myString& ob)const;
bool operator !()const;//判断字符串是否为空
myString& operator = (const myString& ob);//临时变量不能作为非const的引用参数
myString& operator +=(myString& ob);
char& operator[](int i);//返回字符串第i个位置的字符
int Find(myString &pat)const;//查子串,返回第一个子串起始位置,不存在返回-1
};
int myString::Find(myString &pat)const
{
if(pat.curLength > this->curLength)
return -1;
int i=0, j=0;
while(this->ch[i]!=pat.ch[0] && i<this->curLength)//在母串匹配子串第一个字符
{
++i;
} CIRCLE: while(this->ch[i]!=pat.ch[0] && i<this->curLength)//在母串匹配子串第一个字符
{
++i;
} if(i==this->curLength)//抵达母串最大长度还没找到。返回-1
return -1;
else if(this->ch[i] == pat.ch[0])//找到了继续匹配
{
++i, j=1;
while(i<this->curLength && j<pat.curLength && this->ch[i]==pat.ch[j])
{
++i;
++j;
}
if(j == pat.curLength)//抵达子串最大长度,则说明子串在母串内,返回位置
return i-j+1;
else if(i < this->curLength)//没找到子串且母串未抵达最大位置,继续在母串匹配子串第一个字符
goto CIRCLE;
else //母串抵达最大位置且没找到子串,返回-1
return -1;
} }
char& myString::operator[](int i)
{
assert(i<=this->curLength&&i>0);
return this->ch[i-1];
}
myString& myString::operator+=(myString& ob)//这个函数直接strcat(this->ch, ob.ch)就可以成功拼接,但是若这样操作则无法知道字符串的最大长度
{
myString tmp(*this);
delete [] this->ch;
this->ch = new char[this->maxSize+ob.maxSize];
strcpy(this->ch, tmp.ch);
strcat(this->ch, ob.ch);
this->curLength += ob.curLength;
this->maxSize += ob.maxSize;
delete[] tmp.ch;
return *this;
}
bool myString::operator !()const
{
return this->curLength==0;
}
bool myString::operator != (myString& ob)const
{
return strcmp(this->ch, ob.ch) == 0 ? false : true;
}
bool myString::operator == (myString& ob)const
{
return strcmp(this->ch, ob.ch) == 0 ? true : false;
}
myString& myString::operator = (const myString& ob)
{
if(&ob!=this)
{
delete[]ch; this->ch = new char[ob.maxSize];
this->maxSize = ob.curLength;
strcpy(this->ch, ob.ch);
this->curLength = ob.curLength;
}
else
{
cerr<<"String copy error\n";
}
return *this;
} myString myString::operator()(int pos, int len)
{
myString temp;
if(pos<0 || len<=0 || pos+len-1>=this->maxSize)
{
temp.curLength = 0;
temp.ch[0] = '\0';
}
else
{
if(pos+len-1 >= this->curLength)
len = this->curLength-pos;
temp.curLength = len;
for(int i=0,j=pos; i<len; ++i,++j)
temp.ch[i] = this->ch[j];
temp.ch[len] = '\0';
}
return temp;
} int myString::Length()const
{
return this->curLength;
} void myString::print()
{
cout<<this->ch<<endl;
} myString::myString(int sz)
{
this->maxSize = sz;
this->ch = new char[this->maxSize+1];
if(this->ch == NULL)
{
cerr<<"Allocation ERROR\n";
exit(1);
}
this->curLength = 0;
ch[0] = '\0';
} myString::myString(const char *init)
{
int len = strlen(init);
this->maxSize = (len > defaultSize) ? len : defaultSize;
this->ch = new char[this->maxSize+1];
if(this->ch == NULL)
{
cerr<<"Application Memory ERROR\n";
exit(1);
} this->curLength = len;
strcpy(this->ch, init); } myString::myString(const myString& ob)
{
this->maxSize = ob.maxSize;
this->ch = new char[this->maxSize+1];
if(this->ch == NULL)
{
cerr<<"Application Memory ERROR\n";
exit(1);
}
this->curLength = ob.curLength;
strcpy(this->ch, ob.ch); } #endif
#include"header.h" int main()
{
myString st(10), st1("ABCDEFG");
myString st2(st1);
//st.print(), st1.print(), st2.print();
st = st1(0, 4);
cout<<"st = ";
st.print();
cout<<"st1 = ";
st1.print();
st += st1;
cout<<"st + st1 = ";
st.print();
char a = st[5];
cout<<a<<endl;
myString st3("EFGH");
cout<<st1.Find(st3)<<endl;
st3 = st3(0, 3);
cout<<st1.Find(st3)<<endl;
return 0;
}
在实现自定义字符串类的时候遇到两个问题,一个是=号重载时,参数必须为const才能正常赋值。
https://www.cnblogs.com/area-h-p/p/11498481.html
另一个就是模式匹配寻找子串。
我实现的寻找子串的方法只需将母串遍历一遍,即可得到子串位置。
具体操作就是先在母串找到子串的第一个字符,然后检查后面字符是否也同样相同,不同继续在母串后边找与子串第一个字符相同的字符,相同则继续循环匹配,直到抵达子串或母串最大长度,若抵达子串最大长度,即找到子串位置,若没有到母串最大长度,则继续在母串后边找与子串第一个字符相同的字符。以此循环。
C++自定义字符串类的更多相关文章
- c++-重载等号,数组,指针,字符串类
重载 重载=操作符 1先释放旧对象资源 2用一个对象=给另外一个对象 3函数返回值当左值 返回一个引用 4 数组类 Array& operator=(Array& a1); 5 字符串 ...
- C++自定义String字符串类,支持子串搜索
C++自定义String字符串类 实现了各种基本操作,包括重载+号实现String的拼接 findSubStr函数,也就是寻找目标串在String中的位置,用到了KMP字符串搜索算法. #includ ...
- kettle系列-[KettleUtil]kettle插件,类似kettle的自定义java类控件
该kettle插件功能类似kettle现有的定义java类插件,自定java类插件主要是支持在kettle中直接编写java代码实现自定特殊功能,而本控件主要是将自定义代码转移到jar包,就是说自定义 ...
- struts2:遍历自定义字符串数组,遍历Action实例所引用对象中的数组
在struts2:OGNL表达式,遍历List.Map集合:投影的使用一文中已经讲述了OGNL遍历List.Map集合等功能. 本文简单写一个遍历数组的示范程序. 1. 遍历自定义字符串数组 < ...
- [转]掌握 ASP.NET 之路:自定义实体类简介 --自定义实体类和DataSet的比较
转自: http://www.microsoft.com/china/msdn/library/webservices/asp.net/CustEntCls.mspx?mfr=true 发布日期 : ...
- Struts2 请求数据的自动封装 及 自定义转换器类
请求数据自动封装: 实现原理:使用了参数拦截器.struts-default.xml中 <interceptor name="params" class="com. ...
- 第33课 C++中的字符串类
在C语言中学习字符串时,我们使用的是字符数组的概念. C语言中没有真正意义的字符串.为了表达字符串的概念,我们使用了字符数组来模拟字符串. 在应用程序开发中,我们需要大量的处理字符串,如果还用C语言中 ...
- PHP自定义XML类实现数组到XML文件的转换
这两天在公司写和各应用商店应用内搜索的接口,大致就像百度应用内搜索这样的东西,具体可以点下面的链接查看. 百度应用内搜索 有的应用商店需要JSON格式的数据,所以我只需要用下面的语句就可以返回对方服务 ...
- 第11课 Qt中的字符串类
1. 历史遗留问题和解决方案 (1)历史遗留问题 ①C语言不支持真正意义上的字符串 ②C语言用字符数组和一组函数实现字符串操作 ③C语言不支持自定义类型,因此无法获得字符串类型 (2)解决方案 ①从C ...
随机推荐
- Typora使用教程
Typora简介 Typorn 是一款轻便简洁的Markdown编辑器,支持及时渲染技术,这也是与其他Markdown编辑器最显著的区别.及时渲染使得你写Markdown就像是写Word文档一样流畅自 ...
- Mybatis的分页插件com.github.pagehelper
1. 需要引入PageHelper的jar包 如果没有使用maven,那直接把jar包导入到lib文件夹下即可,这个PageHelper插件在github上有开源, 地址为:https://githu ...
- kail入侵win2003 sp2 中文版系统
攻击机:kail -- IP:192.168.74.132 目标靶机:win2003 sp2 中文版系统-- IP:192.168.74.128 一.扫描漏洞 1. 在kail中运行 namp 192 ...
- buuoj刷题 October
2019 极客大挑战 web easysql 直接万能密码登就完事了 LoveSQL 万能密码登进去,给了md5,没解出来 手注吧,都要忘了手注怎么注了 猜字段数 3的时候正常不报错 看回显位,2,3 ...
- 一行导出所有任意微软SQL server数据脚本-基于Python的微软官方mssql-scripter工具使用全讲解
文章标题: 一行导出所有任意微软SQL serer数据脚本-基于Python的微软官方mssql-scripter工具使用全讲解 关键字 : mssql-scripter,SQL Server 文章分 ...
- IDEA下载 使用快捷方式 以及一些小教程
IDEA下载 使用快捷方式 以及一些小教程 Idea下载 网址:链接: https://pan.baidu.com/s/1xRr3mhM6_VDHqC_w0F1MjQ 提取码: 6ypi 下载,安装方 ...
- Linux驱动实践:你知道【字符设备驱动程序】的两种写法吗?
作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...
- SpringCloud升级之路2020.0.x版-37. 实现异步的客户端封装配置管理的意义与设计
本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 为何需要封装异步 HTTP 客户端 WebClient 对于同步的请求,我们使用 spri ...
- Maven 依赖调解源码解析(七):总结
本文是系列文章<Maven 源码解析:依赖调解是如何实现的?>第七篇,也是最后一篇,主要做个总结.请按顺序阅读其他系列文章,系列文章总目录参见:hhttps://www.cnblogs.c ...
- Java安全之基于Tomcat的Filter型内存马
Java安全之基于Tomcat的Filter型内存马 写在前面 现在来说,内存马已经是一种很常见的攻击手法了,基本红队项目中对于入口点都是选择打入内存马.而对于内存马的支持也是五花八门,甚至各大公司都 ...