前言 Try my best to do want i want to do. Time:2017/1/18 name:Willam
1、串的三種表示方式
定長順序存儲表示堆分配表示(比較傾向使用這種)鏈式存儲表示2、完成實現串的基本操作的代碼框架的構建(采用第二種表示方式來實現)
class Mystring{PRivate: char * data; int MAX_SIZE; int length; int step;public: Mystring();//無參構造函數 Mystring(char *);//有參構造函數 Mystring(const Mystring &);//拷貝構造函數 void strassign(char *);//賦值函數,將之前的值全部刪除,替換為新的值 int strlength() const;//返回串的長度 char * getdata() const;//返回串的內容 int strcompare(const Mystring);//比較兩個串的長度 void clear();//釋放內存,清空串的內容 void concat(const Mystring);//連接兩個串的內容 char * substring(int,int);//返回一個子串 friend ostream & Operator <<(ostream &,const Mystring &);////重載“<<};3、操作函數的實現 ①Mystring()函數的實現:
Mystring::Mystring(){ data=NULL; MAX_SIZE=1000; length=0; step=100;}②Mystring(char *)函數的實現
Mystring::Mystring(char * temp){ //初始化MAX_SIZE和step MAX_SIZE=1000; step=100; int i=0; //得到temp字符串的長度(拖底程序效率的一個地方,寫完嘗試優化) while(temp[i++]!='/0'); //如果串的長度,大于我們設定的最大的長度,那么就要對MAX_SIZE做一些修改 length=i-1; if(length>=MAX_SIZE){ MAX_SIZE=length+step; } //為data開辟空間 data=new char[MAX_SIZE]; //為data賦值 //data=temp;這種方法是錯誤的,雖然它可以很快捷的完成初始化,但是它只不過又重新為data定義了一個新的空間,這個空間就是temp開辟的空間 for(i=0;i<=length;i++) data[i]=temp[i];}③Mystring(const Mystring &)函數的實現
Mystring::Mystring(const Mystring & s){ //字符指指針的原理是:比如我們的data是指向存放那個串的第一個字符的內存地址,因為我們的串是存放的連續的內存地址的,并且是以“/0”結尾的,所以我們可以直接通過data來操作整個字符串,同時包括賦值。 data=s.data; length=s.length; MAX_SIZE=s.MAX_SIZE; step=s.step;}④void strassign(char *)函數的實現
void Mystring::strassign(char * temp){ //對于這個函數,我們首先是要先把我們串之前的內容給清空,然后我們再為它重新賦值 data=NULL; length=0; //同樣是先得到temp串的長度 int i=0; while(temp[i++]!='/0'); length=i-1; if(length>=MAX_SIZE) MAX_SIZE=length+step; //為data開辟新的空間 data=new char[MAX_SIZE]; //為data賦值 for(i=0;i<=length;i++) data[i]=temp[i];}⑤int strlength() const;函數的實現 這里我首先解釋一下const的含義:1、const函數不能修改其數據成員,2、const的成員 不能訪問非const的函數,所以對于后面的strcompare函數,如果它的const形參需要訪問這個函數,就要把這個函數聲明為const函數
//const是必須添加的,因為這個是STL的一個機制的問題,如果我們不添加const,在strcompare函數將會報錯int Mystring::strlength()const{ return length;}⑥char * getdata() const函數的實現
char * Mystring::getdata()const{ return data;}⑦int strcompare(const Mystring)函數的實現
int Mystring::strcompare(const Mystring s){ //如果比s的data大,則返回大于0,兩者相等則返回0,小于則返回小于0的數 char *d=s.getdata(); int l=s.strlength(); int i; for(i=0;i<length && i<l;i++) if(data[i]!=d[i]) return data[i]-d[i]; return data[i]-d[i];}⑧void clear();函數的實現
void Mystring::clear(){ length=0; delete data; data=NULL;}⑨void concat(const Mystring);函數的實現
void Mystring::concat(const Mystring s){ int total=length+s.strlength(); int l=s.strlength(); int i=0; //如果data的空間不足以存放兩個串的內容,所以我們需要為它重新開辟一個更大的空間 if(MAX_SIZE<(total+1)) { char *temp=data; MAX_SIZE=total+step; data=new char[MAX_SIZE]; for(i=0;i<=length;i++) { data[i]=temp[i]; } delete temp; temp=NULL; } else{ i=length;//尾巴添加串的位置 } //把s的串接在data的尾部 char * t=s.getdata(); for(int j=0;j<=l;j++){ data[i++]=t[j]; }}⑩char * substring(int,int);函數的實現
//假設下標從1開始,start為想要的字串開始的為位置,而l為其長度char * Mystring::substring(int start,int l){ char * temp; //判斷你想要的子串的起點是否合法 if(start<1 || start>length) { cout<<"你輸入的起始位置不合法"<<endl; return NULL; } //為我們的臨時字符串數組開辟足夠大的空間 temp=new char[l+1]; //j為temp的下標,i為data的下標 int j=0; int i=start-1; //為temp賦值 for(j=0;j<l && i<length;j++,i++) { temp[j]=data[i]; } //為temp字符數組添加一個結尾符號 temp[j]='/0'; return temp;}?friend ostream & operator <<(ostream &,const Mystring &);函數的實現
//重載了“<<”這個運算符,而且是通過友元函數的方式來重載的,所以在使用是可以直接:cout<<類對象名,通過這種格式來輸出串的內容。ostream & operator << (ostream & out,const Mystring & s){ out<<s.data<<endl; return out;//返回輸出流}在運算符重載的中,有兩種重載方式:友元函數重載和成員函數重載,但是一般我們都是使用友元函數重載,除了幾個必須要使用成員函數重載的。具體可以看我之前的博客:運算符重載介紹
3、代碼整合與總結 我是在linux下跑我的代碼的,所以我采用的新建一個工程的方式來實現我的代碼,它包括了四個文件:string.h、string.c、main.c、makefile;
string.h文件的內容
#ifndef STR_H#define STR_H#include<iostream>using namespace std;class Mystring{private: char * data; int MAX_SIZE; int length; int step; public: Mystring();//無參構造函數 Mystring(char *);//有參構造函數 Mystring(const Mystring &);//拷貝構造函數 void strassign(char *);//賦值函數,將之前的值全部刪除,替換為新的值 int strlength() const;//返回串的長度 char * getdata() const; int strcompare(const Mystring);//比較兩個串的長度 void clear();//釋放內存,清空串的內容 void concat(const Mystring);//連接兩個串的內容 char * substring(int,int);//返回一個子串 friend ostream & operator << (ostream &,const Mystring &);//重載“<<”};#endifstring.c文件的內容
#include "string.h"Mystring::Mystring(){ data=NULL; MAX_SIZE=1000; length=0; step=100;}Mystring::Mystring(char * temp){ //初始化MAX_SIZE和step MAX_SIZE=1000; step=100; int i=0; //得到temp字符串的長度(拖底程序效率的一個地方,寫完嘗試優化) while(temp[i++]!='/0'); //如果串的長度,大于我們設定的最大的長度,那么就要對MAX_SIZE做一些修改 length=i-1; if(length>=MAX_SIZE){ MAX_SIZE=length+step; } //為data開辟空間 data=new char[MAX_SIZE]; //為data賦值 //data=temp;這種方法是錯誤的,雖然它可以很快捷的完成初始化,但是它只不過又重新為data定義了一個新的空間,這個空間就是temp開辟的空間 for(i=0;i<=length;i++) data[i]=temp[i];}Mystring::Mystring(const Mystring & s){ //字符指指針的原理是:比如我們的data是指向存放那個串的第一個字符的內存地址,因為我們的串是存放的連續的內存地址的,并且是以“/0”結尾的,所以我們可以直接通過data來操作整個字符串,同時包括賦值。 data=s.data; length=s.length; MAX_SIZE=s.MAX_SIZE; step=s.step;}void Mystring::strassign(char * temp){ //對于這個函數,我們首先是要先把我們串之前的內容給清空,然后我們再為它重新賦值 data=NULL; length=0; //同樣是先得到temp串的長度 int i=0; while(temp[i++]!='/0'); length=i-1; if(length>=MAX_SIZE) MAX_SIZE=length+step; //為data開辟新的空間 data=new char[MAX_SIZE]; //為data賦值 for(i=0;i<=length;i++) data[i]=temp[i];}//const是必須添加的,因為這個是STL的一個機制的問題,如果我們不添加const,在strcompare函數將會報錯int Mystring::strlength()const{ return length;}char * Mystring::getdata()const{ return data;}int Mystring::strcompare(const Mystring s){ //如果比s的data大,則返回大于0,兩者相等則返回0,小于則返回小于0的數 char *d=s.getdata(); int l=s.strlength(); int i; for(i=0;i<length && i<l;i++) if(data[i]!=d[i]) return data[i]-d[i]; return data[i]-d[i];}void Mystring::clear(){ length=0; delete data; data=NULL;}void Mystring::concat(const Mystring s){ int total=length+s.strlength(); int l=s.strlength(); int i=0; //如果data的空間不足以存放兩個串的內容,所以我們需要為它重新開辟一個更大的空間 if(MAX_SIZE<(total+1)) { char *temp=data; MAX_SIZE=total+step; data=new char[MAX_SIZE]; for(i=0;i<=length;i++) { data[i]=temp[i]; } delete temp; temp=NULL; } else{ i=length;//尾巴添加串的位置 } //把s的串接在data的尾部 char * t=s.getdata(); for(int j=0;j<=l;j++){ data[i++]=t[j]; }}//假設下標從1開始,start為想要的字串開始的為位置,而l為其長度char * Mystring::substring(int start,int l){ char * temp; if(start<1 || start>length) { cout<<"你輸入的起始位置不合法"<<endl; return NULL; } temp=new char[l]; int j=0; int i=start-1; for(j=0;j<l && i<length;j++,i++) { temp[j]=data[i]; } temp[j]='/0'; cout<<j<<endl; return temp;}//重載了“<<”這個運算符,而且是通過友元函數的方式來重載的,所以在使用是可以直接:cout<<類對象名,通過這種格式來輸出串的內容。ostream & operator << (ostream & out,const Mystring & s){ out<<s.data<<endl; return out;//返回輸出流}main.c文件的內容 這里面的代碼主要是一些測試的內容,所以基本沒有寫什么
#include "string.h"#include<iostream>using namespace std;int main(){ char * str; str=new char[100]; cin>>str; Mystring test(str); cout<<test<<endl; return 0;}makefile文件的內容 makefile是一個告訴系統如何執行這個程序的一個文件,如果你有了這個文件,只需要在該目錄下打開命令行,輸入make就可以執行程序了,具體可以去百度看看
out:main.o string.o g++ -o out main.o string.omain.o:main.c string.h g++ -c main.cstring.o:string.c string.h g++ -c string.cclean: rm out main.o string.o總結
首先這次有光串的基礎知識的學習,其實你會發現,你現在做的這些內容,STL中的string類都已經幫你做好了,所以我們在這里只是去學習一下string內部實現的一些方式,另外,學習了串的基本操作后,我想寫一個小小的程序:給你一篇英文的文章,你用c++寫個程序,統計里面出現不同單詞的總數和各個單詞出現的頻率。
新聞熱點
疑難解答