//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:
        friend ostream& 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++自定义字符串类的更多相关文章

  1. c++-重载等号,数组,指针,字符串类

    重载 重载=操作符 1先释放旧对象资源 2用一个对象=给另外一个对象 3函数返回值当左值 返回一个引用 4 数组类 Array& operator=(Array& a1); 5 字符串 ...

  2. C++自定义String字符串类,支持子串搜索

    C++自定义String字符串类 实现了各种基本操作,包括重载+号实现String的拼接 findSubStr函数,也就是寻找目标串在String中的位置,用到了KMP字符串搜索算法. #includ ...

  3. kettle系列-[KettleUtil]kettle插件,类似kettle的自定义java类控件

    该kettle插件功能类似kettle现有的定义java类插件,自定java类插件主要是支持在kettle中直接编写java代码实现自定特殊功能,而本控件主要是将自定义代码转移到jar包,就是说自定义 ...

  4. struts2:遍历自定义字符串数组,遍历Action实例所引用对象中的数组

    在struts2:OGNL表达式,遍历List.Map集合:投影的使用一文中已经讲述了OGNL遍历List.Map集合等功能. 本文简单写一个遍历数组的示范程序. 1. 遍历自定义字符串数组 < ...

  5. [转]掌握 ASP.NET 之路:自定义实体类简介 --自定义实体类和DataSet的比较

    转自: http://www.microsoft.com/china/msdn/library/webservices/asp.net/CustEntCls.mspx?mfr=true 发布日期 : ...

  6. Struts2 请求数据的自动封装 及 自定义转换器类

    请求数据自动封装: 实现原理:使用了参数拦截器.struts-default.xml中 <interceptor name="params" class="com. ...

  7. 第33课 C++中的字符串类

    在C语言中学习字符串时,我们使用的是字符数组的概念. C语言中没有真正意义的字符串.为了表达字符串的概念,我们使用了字符数组来模拟字符串. 在应用程序开发中,我们需要大量的处理字符串,如果还用C语言中 ...

  8. PHP自定义XML类实现数组到XML文件的转换

    这两天在公司写和各应用商店应用内搜索的接口,大致就像百度应用内搜索这样的东西,具体可以点下面的链接查看. 百度应用内搜索 有的应用商店需要JSON格式的数据,所以我只需要用下面的语句就可以返回对方服务 ...

  9. 第11课 Qt中的字符串类

    1. 历史遗留问题和解决方案 (1)历史遗留问题 ①C语言不支持真正意义上的字符串 ②C语言用字符数组和一组函数实现字符串操作 ③C语言不支持自定义类型,因此无法获得字符串类型 (2)解决方案 ①从C ...

随机推荐

  1. Android WebView 实现文件选择、拍照、录制视频、录音

    原文地址:Android WebView 实现文件选择.拍照.录制视频.录音 | Stars-One的杂货小窝 Android中的WebView如果不进行相应的设置,H5页面的上传按钮是无法触发And ...

  2. oracle静默安装完成后,重启数据库,错误ORA-01102: cannot mount database in EXCLUSIVE mode

    静默安装oracle完成后,登录数据库激活用户,无法更改,提示未载入数据库,关闭后重启报错: 1.找到安装目录下的$ORACLE_HOME/dbs/ 目录下,查看当前使用lkORCL文件的用户(fus ...

  3. Spring Cloud Gateway实战之一:初探

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于<Spring Cloud Gateway实 ...

  4. 五(二)、spring 声明式事务xml配置

    概述: 接着上一节内容,把注解配置@@Transactional形式改为xml配置形式: 一.配置步骤 1.配置事务管理器 1 <!-- 1配置事务管理器 --> 2 <bean i ...

  5. 安装spark 后 NoClassDefFoundError

    安装spark后,hive报 java.lang.NoClassDefFoundError: org/apache/hadoop/mapreduce/InputFormat trace 看是sqoop ...

  6. RabbitMQ 处理过慢,原来是一个 SQL 缓存框架导致的 GC 频繁触发

    一:背景 1. 讲故事 上个月底,有位朋友微信找到我,说他的程序 多线程处理 RabbitMQ 时过慢,帮忙分析下什么原因,截图如下: 这问题抛出来,有点懵逼,没说CPU爆高,也没说内存泄漏,也没说程 ...

  7. 论文解读(LLE)《Nonlinear Dimensionality Reduction by Locally Linear Embedding》and LLE

    论文题目:<Nonlinear Dimensionality Reduction by Locally Linear Embedding > 发表时间:Science  2000 论文地址 ...

  8. [cf674E]Bear and Destroying Subtrees

    令$f_{i,j}$表示以$i$为根的子树中,深度小于等于$j$的概率,那么$ans_{i}=\sum_{j=1}^{dep}(f_{i,j}-f_{i,j-1})j$ 大约来估计一下$f_{i,j} ...

  9. [cf1209E]Rotate Columns

    题意也可以理解为这样一个过程: 对于每一列,将其旋转后选出若干行上的数,要求与之前的行都不同 用$g_{i,S}$表示第$i$列选出的行数集合为$S$的最大和,$f_{i,S}$表示前$i$列$S$中 ...

  10. 如何用webgl(three.js)搭建处理3D园区、3D楼层、3D机房管线问题(机房升级版)-第九课(一)

    写在前面的话: 说点啥好呢?就讲讲前两天的小故事吧,让我确实好好反省了一下. 前两天跟朋友一次技术对话,对方问了一下Geometry与BufferGeometry的具体不同,我一下子脑袋短路,没点到重 ...