//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. 用STM32定时器中断产生PWM控制步进电机

    控制步进电机可以使用PWM.定时器中断.延时,这里用的就是定时器中断来让它转动. 一.硬件部分1.使用的硬件板子用的是正点原子的STM32F103 mini板,驱动器是DM420(DM420驱动器资料 ...

  2. Laravel/Lumen 分组求和问题 where groupBy sum

    在Laravel中使用分组求和,如果直接使用Laravel各数据库操作方法,应该会得出来如下代码式: DB::table('table_a') ->where('a','=',1) ->g ...

  3. void * 是什么?

    最近遇到void *的问题无法解决,发现再也无法逃避了(以前都是采取悄悄绕过原则),于是我决定直面它. 在哪遇到了? 线程创建函数pthread_create()的最后一个参数void *arg,嗯? ...

  4. windows端口占用处理方法

    (1)输入命令:netstat -ano,列出所有端口的情况.在列表中我们观察被占用的端口,比如是8081,首先找到它.C:\Users\Administrator>netstat -ano活动 ...

  5. go的变量、常量以及判断变量的数据类型

    1.定义变量 p.p1 { margin: 0; font: 12px "Helvetica Neue"; color: rgba(69, 69, 69, 1) } span.s1 ...

  6. LeetCode刷题 树专题

    树专题 关于树的几个基本概念 1 树的节点定义 2 关于二叉树的遍历方法 2.1 前序遍历 2.2 中序遍历 2.3 后序遍历 2.4 层序遍历 3 几种常见的树介绍 3.1 完全二叉树 3.2 二叉 ...

  7. java.lang.NoSuchFieldError: REFLECTION

    2020-09-14 09:13:21.415 INFO org.apache.cxf.service.factory.ReflectionServiceFactoryBean Line:457 - ...

  8. SpringCloud升级之路2020.0.x版-34.验证重试配置正确性(1)

    本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 在前面一节,我们利用 resilience4j 粘合了 OpenFeign 实现了断路器. ...

  9. [loj3049]字符串问题

    考虑将所有A串向所能支配的B串连边,B串向满足B串是A串前缀的A串连边,在A串上有点权,跑最长路即可但这样前缀的边太多,考虑优化:在后缀树上,将这些串插入进去(注意相同的串A串要在B串下面),并将父亲 ...

  10. SpringCloud升级之路2020.0.x版-40. spock 单元测试封装的 WebClient(下)

    本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 我们继续上一节,继续使用 spock 测试我们自己封装的 WebClient 测试针对 r ...