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;
	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

另一个就是模式匹配寻找子串。

我实现的寻找子串的方法只需将母串遍历一遍,即可得到子串位置。

具体操作就是先在母串找到子串的第一个字符,然后检查后面字符是否也同样相同,不同继续在母串后边找与子串第一个字符相同的字符,相同则继续循环匹配,直到抵达子串或母串最大长度,若抵达子串最大长度,即找到子串位置,若没有到母串最大长度,则继续在母串后边找与子串第一个字符相同的字符。以此循环。

猜你喜欢

转载自www.cnblogs.com/area-h-p/p/11508305.html