c++中string类的源代码


一:回顾

(1)c++中的string类是在面试中和笔试中经常考的题目; 工程代码免费下载 string类的自行实现

(2)c++中的string类和fstream类合起来是处理外部数据的利器

(3)string类经常用到find find_first_of find_first_not_of find_last_of find_last_not_of substr replace等,以及联合使用来达到java中的split和trim

  (4) 使用friend 仅仅是在类中进行声明的非内部 却可以访问内部成员的外部函数,而且在外部不再需要friend关键字;它与成员函数的区别是,friend和外部函数不含有this对象指针;本文用到了const 定义的全局最大值最小值变量(代替#define)

 (5) 有些函数返回的是MyString& 、Char& 等(引用),MyString、Char 等(传值)这得看你返回的对象是函数的局部变量还是全局变量(或者类当前对象成员变量);前者只能返回一个MyString、Char 等;后者强烈建议返回MyString& 、Char& 等(引用);

(6)有些函数的参数是const MyString& ,有些是MyString& (引用);这是为什么?前者是把外部值传提到子函数内部,且不允许改变;后者是作为函数的返回值传递进去的,返回的结果为函数的处理结果(而不用函数自身返回值了)。

二:下面是简单的实现了一下string类,参照的是STL源码,但是自己理解的还是不够深,难免有一些错误,请各位指教

(1)MyString.h文件

  1. #ifndef MYSTRING_H  
  2. #define MYSTRING_H  
  3. #include "MyExcept.h"  
  4. #include <cstring>  
  5. #include <iostream>  
  6. const int INI_MAX = 0x7fffffff;//2^32npos  
  7. const int INI_MIN = 0x80000000;// -2^32  
  8. const int npos = 0xffffffff;// npos  
  9. using namespace std;  
  10.   
  11. class MyString  
  12. {  
  13.     public:  
  14.     // constructor  
  15.     MyString();//  
  16.     MyString(const MyString &);//  
  17.     MyString(const char *);  
  18.     MyString(const size_t,const char);  
  19.     // destructor  
  20.     ~MyString();  
  21.     // attributes  
  22.   
  23.     size_t length();// 字符串长度  
  24.     bool isEmpty();// 返回字符串是否为空  
  25.     const char* c_str();// 返回c风格的trr的指针  
  26.     // friend funs  
  27.     // read writer operations  
  28.     friend ostream& operator<< (ostream&, const MyString&);  
  29.     friend istream& operator>> (istream&, MyString&);  
  30.     //add operation  
  31.     friend MyString operator+(const MyString&,const MyString&);  
  32.     // compare operations  
  33.     friend bool operator==(const MyString&,const MyString&);  
  34.     friend bool operator!=(const MyString&,const MyString&);  
  35.     friend bool operator<(const MyString&,const MyString&);  
  36.     friend bool operator<=(const MyString&,const MyString&);  
  37.     friend bool operator>(const MyString&,const MyString&);  
  38.     friend bool operator>=(const MyString&,const MyString&);  
  39.     // 成员函数实现运算符重载,其实一般需要返回自身对象的,成员函数运算符重载会好一些  
  40.     // index operation  
  41.     char& operator[](const size_t);  
  42.     const char& operator[](const size_t)const;  
  43.     // =  
  44.     MyString& operator=(const MyString&);  
  45.     // +=  
  46.     MyString& operator+=(const MyString&);  
  47.     // +=  
  48.     //MyString operator+=(const MyString&); cannot be overloaded  
  49.     // 成员操作函数  
  50.     // substr  
  51.     MyString substr(size_t pos,const size_t n);  
  52.     // append  
  53.     MyString& append(const MyString&);  
  54.     //insert  
  55.     MyString& insert(size_t,const MyString&);  
  56.     //assign 替换  
  57.     MyString& assign(MyString&,size_t,size_t);  
  58.     // erase 删除  
  59.     MyString& erase(size_t,size_t);  
  60.     //find_first_of 查找某一个字符 size_t 是非符号数的,重载  
  61.     // 查找在字符串中第一个与str中的某个字符匹配的字符,返回它的位置。  
  62.     //搜索从index开始,如果没找到就返回string::npos  
  63.     int find_first_of(const char* str,size_t index=0);  
  64.     int find_first_of(const char ch,size_t index=0);  
  65.     int find_first_of(const MyString &,size_t index=0);  
  66.     // 在字符串中查找第一个与str中的字符都不匹配的字符,返回它的位置。搜索从index开始。如果没找到就返回string::nops  
  67.     int find_first_not_of(const char* str,size_t index=0);  
  68.     int find_first_not_of(const char ch,size_t index=0);  
  69.     int find_first_not_of(const MyString&,size_t index=0);  
  70.     // swap  
  71.     void swap(MyString& lhs,MyString& rhs);  
  72.     // replace_all  
  73.     MyString& replace_all(const char oldc,const char newc=NULL);  
  74.     MyString& replace(size_t index,size_t num1,size_t num2,const char ch);  
  75.     //find  
  76.     int find(const char* str,size_t index=0);  
  77.     int find(const MyString& str,size_t index=0);  
  78.     int find(const char ch,size_t index=0);  
  79.   
  80.   
  81.     //private  
  82.     private:  
  83.     char *p_str;  
  84.     size_t strLength;  
  85. };  
  86.   
  87.   
  88. #endif // MYSTRING_H  

(2)MyString.cpp文件

  1. #include "MyString.h"  
  2. #include <cassert>  
  3.   
  4. // constructor  
  5.     MyString::MyString():p_str(NULL),strLength(0){}  
  6.   
  7.     MyString::MyString(const MyString &str)//  
  8.     {  
  9.         if(NULL == str.p_str)  
  10.         {  
  11.             return;  
  12.         }  
  13.         strLength = str.strLength;  
  14.         p_str = new char[strLength+1];  
  15.         strcpy(p_str,str.p_str);  
  16.     }  
  17.     MyString::MyString(const char *str)  
  18.     {  
  19.         if(NULL == str)  
  20.         {  
  21.             return;  
  22.         }  
  23.         strLength = strlen(str);  
  24.         p_str = new char[strLength+1];  
  25.         strcpy(p_str,str);  
  26.     }  
  27.     MyString::MyString(const size_t len,const char ch)  
  28.     {  
  29.         if(NULL == ch)  
  30.         {  
  31.             return;  
  32.         }  
  33.         strLength = len;  
  34.         p_str = new char[strLength+1];  
  35.         for(size_t i=0;i<strLength;i++)  
  36.         {  
  37.             p_str[i] = ch;  
  38.         }  
  39.         p_str[strLength] = '\0';// 因为strset以'\0'结束的  
  40.         cout << p_str << " &&" << endl;  
  41.         //strset(p_str,ch);  
  42.         //cout << p_str[0] << ",,,"<<strlen(p_str) << "," << strLength << endl;  
  43.     }  
  44.     // destructor  
  45.     MyString::~MyString()  
  46.     {  
  47.         delete[] p_str;  
  48.     }  
  49.   
  50.     // attributes  
  51.     size_t MyString::length()// 字符串长度  
  52.     {  
  53.         return strLength;  
  54.     }  
  55.     bool MyString::isEmpty()// 返回字符串是否为空  
  56.     {  
  57.         return strLength==0?true:false;  
  58.     }  
  59.     const char* MyString::c_str()  
  60.     {  
  61.         return p_str;  
  62.     }  
  63.     // 为什么不是引用呢??? friend 使用在类里面进行声明的,外面就不需要了,而且友元函数不属于类的成员函数,所以不用MyString::  
  64.     // ostream  
  65.     ostream& operator<< (ostream& out,const MyString &str)  
  66.     {  
  67.         if(str.p_str != NULL)  
  68.         {  
  69.             out << str.p_str;  
  70.         }  
  71.         return out;  
  72.     }  
  73.     // istream,一个是const另一个不是,根据变还是不变  
  74.     istream& operator>> (istream& in, MyString& str)  
  75.     {  
  76.         char tmp[100];// 临时字符串  
  77.         if(in>>tmp)  
  78.         {  
  79.             delete[] str.p_str;  
  80.             str.strLength = strlen(tmp);  
  81.             str.p_str = new char[str.strLength+1];  
  82.             strcpy(str.p_str,tmp);  
  83.         }  
  84.         return in;  
  85.     }  
  86.     // + 加  
  87.     MyString operator+(const MyString& lhs,const MyString& rhs)  
  88.     {  
  89.         MyString ret;  
  90.         ret.strLength = lhs.strLength + rhs.strLength;  
  91.         ret.p_str = new char[ret.strLength+1];  
  92.         strcpy(ret.p_str,lhs.p_str);  
  93.         strcat(ret.p_str,rhs.p_str);  
  94.         return ret;  
  95.     }  
  96.     // compare operations  
  97.     bool operator==(const MyString& lhs,const MyString& rhs)  
  98.     {  
  99.         return strcmp(lhs.p_str,rhs.p_str)==0?true:false;  
  100.     }  
  101.     bool operator!=(const MyString& lhs,const MyString& rhs)  
  102.     {  
  103.         return strcmp(lhs.p_str,rhs.p_str)!=0?true:false;  
  104.     }  
  105.     bool operator<(const MyString& lhs,const MyString& rhs)  
  106.     {  
  107.         return strcmp(lhs.p_str,rhs.p_str)<0?true:false;  
  108.     }  
  109.     bool operator<=(const MyString& lhs,const MyString& rhs)  
  110.     {  
  111.         return strcmp(lhs.p_str,rhs.p_str)<=0?true:false;  
  112.     }  
  113.     bool operator>(const MyString& lhs,const MyString& rhs)  
  114.     {  
  115.         return strcmp(lhs.p_str,rhs.p_str)>0?true:false;  
  116.     }  
  117.     bool operator>=(const MyString& lhs,const MyString& rhs)  
  118.     {  
  119.         return strcmp(lhs.p_str,rhs.p_str)>=0?true:false;  
  120.     }  
  121.     // 成员函数实现运算符重载  
  122.     // index operation  
  123.     char& MyString::operator[](const size_t index)  
  124.     {  
  125.         if(index<0 || index>=strLength)  
  126.         {  
  127.             throw Outofbond() ;  
  128.         }  
  129.         return p_str[index];  
  130.     }  
  131.     const char& MyString::operator[](const size_t index)const  
  132.     {  
  133.         if(index<0 || index>=strLength)  
  134.         {  
  135.             throw Outofbond();  
  136.         }  
  137.         return p_str[index];  
  138.     }  
  139.      // = 赋值构造函数(判断是否是自身) 为什么要这样删除呢?  
  140.     MyString& MyString::operator=(const MyString& other)  
  141.     {  
  142.         if(this != &other)  
  143.         {  
  144.             if(strLength<other.strLength)  
  145.             {  
  146.                 delete[] p_str;  
  147.                 p_str = new char[other.strLength+1];  
  148.             }  
  149.             strLength = other.strLength;  
  150.             strcpy(p_str,other.p_str);  
  151.         }// 这样可能会产生多余的未释放的空间  
  152.         return *this;  
  153.     }  
  154.     // += 相当于返回的是备份的,内部对象的销毁,不影响的 和 下面的完全不一样的  
  155. //    MyString MyString::operator+=(const MyString& other)  
  156. //    {  
  157. //        if(NULL == other.p_str)  
  158. //        {  
  159. //            return *this;  
  160. //        }  
  161. //        MyString ret;  
  162. //        ret.strLength = strLength + other.strLength;  
  163. //        ret.p_str = new char[ret.strLength+1];  
  164. //        strcpy(ret.p_str,p_str);  
  165. //        strcat(ret.p_str,other.p_str);  
  166. //        return ret;  
  167. //    }  
  168.     // 返回的是当前对象的引用,当前对象就在调用函数里,所以不会销毁的  
  169.     // 判断一下是否是自身相加  
  170.     MyString& MyString::operator+=(const MyString& other)  
  171.     {  
  172.         if(NULL == other.p_str)  
  173.         {  
  174.             return *this;  
  175.         }  
  176.         if(this == &other)  
  177.         {  
  178.             MyString copy(*this);  
  179.             return *this += copy;  
  180.         }// 必须判断是否相等的,而且要+=的,这样相当于调用了自身,但是这次直接下面去了,不进入if的  
  181.         strLength += other.strLength;  
  182.         //strLength *= 2;  
  183.         char *p_old = p_str;  
  184.         p_str = new char[strLength+1];  
  185.         strcpy(p_str,p_old);  
  186.         strcat(p_str,other.p_str);  
  187.         delete[] p_old;// 删除旧的空间  
  188.         return *this;  
  189.     }  
  190.     // 成员操作函数  
  191.     // substr  返回应用是不行的,错误的;取从pos开始的n个字符组成的子串  
  192.     //MyString& MyString::substr(size_t pos,const size_t n)  
  193.     MyString MyString::substr(size_t pos,const size_t n)  
  194.     {  
  195.         if((pos+n)>=strLength)  
  196.         {  
  197.             throw Outofbond();  
  198.         }  
  199.         MyString ret;  
  200.         ret.strLength = n;  
  201.         //ret.p_str = new char[n+1];  
  202.         ret.p_str = new char[ret.strLength+1]; //也可以  
  203.         for(size_t i=0;i<n;i++)  
  204.         {  
  205.             ret.p_str[i] = p_str[pos+i];  
  206.         }  
  207.         ret.p_str[n] = '\0';  
  208. //        for(size_t i=0;i<ret.strLength;i++)  
  209. //        {  
  210. //            ret[i] = (*this)[pos+i];  
  211. //            cout << ret[i] << ",,";  
  212. //        }// 也行的,利用刚刚重载的【】,这样更好,不用再次判断越界了,不知道为什么,报错误的  
  213. //        ret[ret.strLength] = '\0';  
  214.         return ret;  
  215.     }  
  216.     // append 同 += 追加到末尾  
  217.     MyString& MyString::append(const MyString& other)  
  218.     {  
  219.         *this += other;// 利用刚刚那重载的+=  
  220.         return *this;  
  221.     }  
  222.     //insert 从pos开始的插入other  
  223.     MyString& MyString::insert(size_t pos,const MyString& other)  
  224.     {  
  225.         if(pos<0 || pos>=strLength)  
  226.         {  
  227.             throw Outofbond();  
  228.         }  
  229.         char *p_old = p_str;  
  230.         strLength += other.strLength;  
  231.         p_str = new char[strLength+1];  
  232.         for(size_t i=0;i<pos;i++)  
  233.         {  
  234.             *(p_str+i) = *(p_old+i);  
  235.         }  
  236.         for(size_t i=pos;i<other.strLength+pos;i++)  
  237.         {  
  238.             *(p_str+i) = other.p_str[i-pos];  
  239.         }  
  240.         for(size_t i=other.strLength+pos;i<strLength;i++)  
  241.         {  
  242.             *(p_str+i) = p_old[i-other.strLength];  
  243.         }  
  244.         *(p_str+strLength) = '\0';  
  245.         return *this;  
  246.     }  
  247.     //assign 替换  用other的POS开始的n对应替换this的pos开始的  
  248.     MyString& MyString::assign(MyString&other,size_t pos,size_t n)  
  249.     {  
  250. //        if(pos<0 || pos>=strLength)  
  251. //        {  
  252. //            throw Outofbond();  
  253. //        }  
  254.         assert(pos>0 && pos<strLength);// assert 的好处  
  255.         assert(pos+n<other.strLength);  
  256.         if(strLength < pos + n)  
  257.         {  
  258.             char *p_old = p_str;  
  259.             strLength = pos + n;  
  260.             p_str = new char[strLength+1];  
  261.             for(size_t i=0;i<pos;i++)  
  262.             {  
  263.                 *(p_str+i) = *(p_old+i);  
  264.             }  
  265.             delete[] p_old;  
  266.         }  
  267.         for(size_t i=pos;i<pos+n;i++)  
  268.         {  
  269.             *(p_str+i) = other.p_str[i];  
  270.         }  
  271.         *(p_str+pos+n) = '\0';  
  272.         return *this;  
  273.     }  
  274.     // erase 删除 这个方法并不是很好的,并没有释放所erase的空间,请看下面的  
  275. //    MyString& MyString::erase(size_t pos,size_t n)  
  276. //    {  
  277. //        if((pos+n)>strLength)  
  278. //        {  
  279. //            throw Outofbond();  
  280. //        }  
  281. //        size_t index = pos + n;  
  282. //        while(*(p_str+index)!='\0')  
  283. //        {  
  284. //            *(p_str+index-n) = *(p_str+index);  
  285. //            ++index;  
  286. //        }  
  287. //        *(p_str+index-n) = '\0';  
  288. //        return *this;  
  289. //    }  
  290.     // erase 删除 从pos开始的n个字符  
  291.     MyString& MyString::erase(size_t pos,size_t n)  
  292.     {  
  293.         if((pos+n)>strLength)  
  294.         {  
  295.             throw Outofbond();  
  296.         }  
  297.         char *p_old = p_str;  
  298.         strLength -= n;  
  299.         p_str = new char[strLength+1];  
  300.         for(size_t i=0;i<pos;i++)  
  301.         {  
  302.             p_str[i] = p_old[i];  
  303.         }  
  304.         for(size_t i=pos;i<strLength;i++)  
  305.         {  
  306.             p_str[i] = p_old[i+n];  
  307.         }  
  308.         *(p_str+strLength) = '\0';  
  309.         return *this;  
  310.     }  
  311.     //find_first_of 查找某一个字符 size_t 是非符号数的  
  312.     // 查找在字符串中第一个与str中的某个字符匹配的字符,返回它的位置。  
  313.     //搜索从index开始,如果没找到就返回string::npos  
  314.     int MyString::find_first_of(const char* str,size_t index)  
  315.     {  
  316.         if(NULL == str || index >=strLength)  
  317.             return npos;  
  318.         int tmp_len = strlen(str),j;  
  319.         size_t flag,min_index = INI_MAX;  
  320.         for(j=0;j<tmp_len;j++)  
  321.         {  
  322.             flag = npos;  
  323.             for(size_t i=index;i<strLength;i++)  
  324.             {  
  325.                 if(str[j] == p_str[i])  
  326.                 {  
  327.                     flag = i;  
  328.                     break;  
  329.                 }  
  330.             }  
  331. //            indexs[j] = flag;  
  332.             if(flag != npos)  
  333.             {  
  334.                 min_index = min_index<flag?min_index:flag;  
  335.             }  
  336.         }  
  337. //        for(j=0;j<tmp_len;j++)  
  338. //        {  
  339. //            if(indexs[j]!=npos)  
  340. //                min = min<indexs[j]?min:indexs[j];  
  341. //        }  
  342.         if(min_index == INI_MAX)  
  343.         {  
  344.             return npos;  
  345. //            min_index = npos;  
  346. //           cout << "---npos----" << min_index << ",,,,";  
  347.         }  
  348.         return min_index;  
  349.     }  
  350.     int MyString::find_first_of(const char ch,size_t index)  
  351.     {  
  352.         if(NULL == ch || index >=strLength)  
  353.             return npos;  
  354.         int j;  
  355.         size_t flag = npos;  
  356.         for(size_t i=index;i<strLength;i++)  
  357.         {  
  358.             if(ch == p_str[i])  
  359.             {  
  360.                 flag = i;  
  361.                 break;  
  362.             }  
  363.         }  
  364.         return flag;  
  365.     }  
  366.     int MyString::find_first_of(const MyString& str,size_t index)  
  367.     {  
  368.         if(NULL == str || index >=strLength)  
  369.             return npos;  
  370.         int j;  
  371.         size_t flag,min_index = INI_MAX;  
  372.         for(j=0;j<str.strLength;j++)  
  373.         {  
  374.             flag = npos;  
  375.             for(size_t i=index;i<strLength;i++)  
  376.             {  
  377.                 if(str[j] == p_str[i])  
  378.                 {  
  379.                     flag = i;  
  380.                     break;  
  381.                 }  
  382.             }  
  383.             if(flag != npos)  
  384.             {  
  385.                 min_index = min_index<flag?min_index:flag;  
  386.             }  
  387.         }  
  388.         if(min_index == INI_MAX)  
  389.         {  
  390.             return npos;  
  391.         }  
  392.         return min_index;  
  393.     }  
  394.     // 在字符串中查找第一个与str中的字符都不匹配的字符,返回它的位置。  
  395.     //搜索从index开始。如果没找到就返回string::nops O(N^2)  
  396.     int MyString::find_first_not_of(const char *str,size_t index)  
  397.     {  
  398.         if(NULL == str || index >=strLength)  
  399.             return npos;  
  400.         size_t i=0,j=0;  
  401.         size_t tmp_len = strlen(str);  
  402.         for(i=index;i<strLength;i++)  
  403.         {  
  404.             for(;j<tmp_len;j++)  
  405.             {  
  406.                 if(p_str[i]==str[j])  
  407.                     break;  
  408.             }  
  409.             if(j==tmp_len)  
  410.                 break;// 根据跳出的内层for的条件判断,找到即结束循环  
  411.         }  
  412.         if(i==strLength)  
  413.             return npos;// 未找到,// 根据跳出的内层for的条件判断,找到即结束循环  
  414.         return i;  
  415.     }  
  416.     int MyString::find_first_not_of(const MyString& str,size_t index)  
  417.     {  
  418.         if(NULL == str || index >=strLength)  
  419.             return npos;  
  420.         size_t i=0,j=0;  
  421.         for(i=index;i<strLength;i++)  
  422.         {  
  423.             for(;j<str.strLength;j++)  
  424.             {  
  425.                 if(p_str[i]==str[j])  
  426.                     break;// 如果相等 本轮i就无效了,进行下一轮  
  427.             }  
  428.             if(j==str.strLength)  
  429.                 break;// 根据跳出的内层for的条件判断,找到即结束循环  
  430.         }  
  431.         if(i==strLength)  
  432.             return npos;// 未找到,// 根据跳出的内层for的条件判断,找到即结束循环  
  433.         return i;  
  434.     }  
  435.     int MyString::find_first_not_of(const char ch,size_t index)  
  436.     {  
  437.         if(NULL == ch || index >=strLength)  
  438.             return npos;  
  439.         size_t i=0;  
  440.         for(i=index;i<strLength;i++)  
  441.         {  
  442.             if(p_str[i]!=ch)// 跟上面的略微不同,找一个不等就可以了  
  443.                 break;  
  444.         }  
  445.         if(i==strLength)  
  446.             return npos;// 未找到,// 根据跳出的内层for的条件判断,找到即结束循环  
  447.         return i;  
  448.     }  
  449.     // swap  都得变得,所以非const  
  450.     void MyString::swap(MyString& lhs,MyString& rhs)  
  451.     {  
  452.         lhs.strLength ^= rhs.strLength;  
  453.         rhs.strLength ^= lhs.strLength;  
  454.         lhs.strLength ^= rhs.strLength;  
  455.         char *p_tmp = rhs.p_str;  
  456.         rhs.p_str = lhs.p_str;  
  457.         lhs.p_str = p_tmp;  
  458.     }  
  459.     // replace_all  这个东西还是不太好弄的啊,不是很理想  
  460.     MyString& MyString::replace_all(const char oldc,const char newc)  
  461.     {  
  462.         if(NULL == oldc)  
  463.         {  
  464.             return *(this);  
  465.         }  
  466.         for(size_t i=0;i<strLength;i++)  
  467.         {  
  468.             if(p_str[i] == oldc)  
  469.             {  
  470.                 p_str[i] = newc;  
  471.             }  
  472.         }  
  473.         return *(this);  
  474.     }  
  475.     MyString& MyString::replace(size_t index,size_t num1,size_t num2,const char ch)  
  476.     {  
  477.   
  478.     }  
  479.     // find 函数  
  480.     int MyString::find(const char* str,size_t index)  
  481.     {  
  482.         assert(str!=NULL&&index<strLength);  
  483.         // kmp 中的getnext函数  
  484.         size_t len = strlen(str);  
  485.         size_t next[len+1];  
  486.         size_t j,k;  
  487.         next[0] = npos;  
  488.         j = 0;  
  489.         k = npos;  
  490.         while(j<len)  
  491.         {  
  492.             if(k==npos || str[j]==str[k])  
  493.             {  
  494.                 j++;  
  495.                 k++;  
  496.                 next[j] = k;  
  497.             }  
  498.             else  
  499.                 k = next[k];  
  500.         }  
  501.         // kmp 算法  
  502.         k = index;  
  503.         j = 0;  
  504.         while(p_str[k]!='\0')  
  505.         {  
  506.             if(j==0 || p_str[k]==str[j])  
  507.             {  
  508.                 k++;  
  509.                 j++;  
  510.             }  
  511.             else  
  512.             {  
  513.                 j = next[j];// 消除指针回溯  
  514.             }  
  515.             if(str[j] == '\0')//匹配成功  
  516.                 return k-j;  
  517.         }  
  518.         return npos;  
  519.     }  
  520.     int MyString::find(const MyString& str,size_t index)  
  521.     {  
  522. //        if(this == &str)  
  523. //        {  
  524. //            MyString other(*this);  
  525. //            find(other,index);  
  526. //        }  
  527.         assert(NULL!=str && index<strLength);  
  528.         // kmp 中的getnext函数  
  529.   
  530.         size_t next[str.strLength+2];  
  531.         size_t j,k;  
  532.         next[0] = npos;  
  533.         j = 0;  
  534.         k = npos;  
  535.         while(j<str.strLength)  
  536.         {  
  537.             if(k==npos || str.p_str[j]==str.p_str[k])  
  538.             {  
  539.                 j++;  
  540.                 k++;  
  541.                 next[j] = k;  
  542.             }  
  543.             else  
  544.                 k = next[k];  
  545.         }  
  546.         int i;  
  547.         for(i=1;i<=j;i++)  
  548.             cout << next[i] << ",";  
  549.         // kmp 算法  
  550.         k = index;  
  551.         j = 0;  
  552.         while(p_str[k]!='\0')  
  553.         {  
  554.             if(j==0 || p_str[k]==str.p_str[j])  
  555.             {  
  556.                 k++;  
  557.                 j++;  
  558.             }  
  559.             else  
  560.             {  
  561.                 j = next[j];// 消除指针回溯  
  562.             }  
  563.             if(str.p_str[j] == '\0')//匹配成功,不知道为什么调用自身的str[]重载总是报错的  
  564.                 return k-j;  
  565.         }  
  566.         if(str.p_str[j] == '\0')// 同一个字符串  
  567.             return k-j;  
  568.         return npos;  
  569.     }  
  570.     int MyString::find(const char ch,size_t index)  
  571.     {  
  572.         assert(NULL!=ch && index<strLength);  
  573.         for(size_t i=index;i<strLength;i++)  
  574.         {  
  575.             if(p_str[i] == ch)  
  576.                 return i;  
  577.         }  
  578.         return npos;  
  579.     }  


(3)测试函数main.cpp
  1. #include "MyString.h"  
  2. #include <iostream>  
  3. using namespace std;  
  4.   
  5. int main()  
  6. {  
  7.     int n;  
  8.     int choose = 1;  
  9.     int p,l;  
  10.     char cs[100];  
  11.     MyString s1;  
  12.     MyString s2("hello");  
  13.     MyString s3 = "HELLO";  
  14.     cout << "***** welcome *****\n";  
  15.     cout << "******* MADE BY zyp **********\n";  
  16.     cout << "s1= " << s1 << "s2= " << s2 << "s3= " << s3 << endl;  
  17.     cout << "请输入一个长度小于100的字符串:例如world\n";  
  18.     cin >> s1;  
  19.     s1 = s1;  
  20.     //s1 = s1+s1;  
  21.     s1 += s1;  
  22.     MyString s4(s1);  
  23.     s4.append(s1);  
  24.     s2.insert(2,s3);  
  25.     s1.erase(4,4);  
  26.     s1.assign(s2,1,7);  
  27.     cout << "s1= " << s1 << "s2= " << s2 << "s3= " << s3 << "s4= " << s4 << endl;  
  28.     s2 = s4.substr(2,7);  
  29.     cout << "s4[3]= " << s4[3] << s4.length() << (s1>=s2) << "s4.substr() " << s2 << endl;  
  30.     cout << "s1.find_first_of(beLE,2):" << s1.find_first_of("beLE",2) << ",s1.find_first_of(a,3):" << s1.find_first_of('a',3) << ",s1.find_first_of(s3,2):" << s1.find_first_of(s3,2) << endl;  
  31.     MyString s5(5,'b');  
  32.     s5 += s5;  
  33.     //s5.append(s5);// 不知道为什就是不能append  
  34.     cout << "s5 = " << s5 << "s5.find_first_not_of(aeHLEOl,2):" << s5.find_first_not_of("aeHLEOl",2) << "s5.find_first_not_of(aeHLEOl,0):" << s5.find_first_not_of("aeHLEOl") << endl;  
  35.     cout << "s5.find_first_not_of(s1,2):" << s5.find_first_not_of(s1,2) << "s5.find_first_not_of(b,2):" << s5.find_first_not_of('b',2) << endl;  
  36.     swap(s1,s5);  
  37.     s5.replace_all('a','J');  
  38.     MyString s6("LLO");  
  39.     cout << s1 << "," << s5 << "s5.find(LLO,0) " << s5.find("LLO",0) << "s5.find(s6,0) " << s5.find(s5) << endl;  
  40.     cout << npos << endl;  
  41.     return 0;  
  42. }  


三:感悟

(1)耗时将近2天的实现了它,自己与其从中学到了很多,倒不如说是重新认识了string类;

(2)自己知道这个简单的string类,距离string源代码还差的很远很远;但是它帮助我更好的理解了string类,至少会简单的应用了。

(3)简单的实现了一下string类,参照的是STL源码,但是自己理解的还是不够深,难免有一些错误,请各位指教,万分感谢!

(4)下一步进军list

猜你喜欢

转载自blog.csdn.net/windgs_yf/article/details/80816568