//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
另一個就是模式匹配尋找子串。
我實現的尋找子串的方法只需將母串遍歷一遍,即可得到子串位置。
具體操作就是先在母串找到子串的第一個字符,然后檢查后面字符是否也同樣相同,不同繼續在母串后邊找與子串第一個字符相同的字符,相同則繼續循環匹配,直到抵達子串或母串最大長度,若抵達子串最大長度,即找到子串位置,若沒有到母串最大長度,則繼續在母串后邊找與子串第一個字符相同的字符。以此循環。