1,字符串类中的新功能(本文代码已集成到字符串类——字符串类的创建(上)中,这里讲述函数实现原理):
2,子串查找(KMP 算法直接运用):
1,int indexOf(const char* s) const;
2,int indexOf(const String& s) const;
3,子串查找成员函数的声明:
int indexOf(const char* ) const;
int indexOf(const String& s) const;
4,子串查找成员函数的定义:
1 int String::indexOf(const char* s) const // 子串查找,返回下标 2 { 3 return kmp(m_str, s ? s : ""); 4 } 5 6 int String::indexOf(const String &s) const 7 { 8 return kmp(m_str, s.m_str); 9 }
3,在字符串中将指定的子串删除:
1,String& remove(const char* s);
2,String& remove(const String& s);
1,根据 kmp 在目标字符串中查找子串的位置;
2,通过子串位置和子串长度进行删除;
3,删除指定字符串成员函数的声明:
String& remove(int i, int len);
String& remove(const char* s);
String& remove(const String& s);
4,删除指定字符串成员函数的定义:
1 /* 删除下标 i 处长度为 len 的字符串 */ 2 String& String::remove(int i, int len) // 和 insert() 返回的是相同的函数,还可以以字符串类继续访问,如查看删除后的字符串等 3 { 4 if( (0 <= i ) && (i < m_length) ) 5 { 6 int n = i; 7 int m = i + len; // 在 (n, m) 范围之内的字符都要删除掉 8 9 while( (n < m) && (m < m_length) ) // 删除的字符串长度是不能大于当前的长度的,否则没有意义 10 { 11 m_str[n++] = m_str[m++]; // 这个赋值很经典 12 } 13 14 m_str[n] = '\0'; //这里为什么是 n,因为n是不断增加的,直到 m 为等于 length 15 m_length = n; // 不应该是 m_length - n 吗? 16 } 17 18 return *this; 19 } 20 21 String& String::remove(const char *s) // 删除子串 22 { 23 return remove(indexOf(s), s ? strlen(s) : 0); 24 } 25 26 String& String::remove(const String &s) // 删除子串 27 { 28 return remove(indexOf(s), s.length()); 29 }
4,字符串的减法操作定义(operator - ):
1,使用 remove 实现字符串间的减法操作;
1,字符串自身不被修改;
2,返回产生的新串;
2,减法操作符重载的声明:
String operator - (const String& s) const;
String operator - (const char* s) const;
String& operator -= (const String& s);
String& operator -= (const char* s);
3,减法操作符重载的定义:
1 String String::operator - (const String& s) const // 字符串自身会被改变 2 { 3 return String(*this).remove(s); // 直接调用构造函数产生一个新的临时字符串对象,值和当前字符串对象值相同,然后调用临时对象的remove() 函数将子串删除,最后将删除结果返回,但是当前的字符串没有被改变,因为是拷贝赋值 4 } 5 6 String String::operator - (const char* s) const // 字符串自身会被改变 7 { 8 return String(*this).remove(s); 9 } 10 11 String& String::operator -= (const String& s) // 字符串自生不会被改变 12 { 13 return remove(s); 14 } 15 16 String& String::operator -= (const char* s) 17 { 18 return remove(s); 19 }
5,字符串中的子串替换:
1,String& replace(const char* t, const char* s);
2,String& replace(const String& t, const char* s);
3,String& replace(cosnt char* t, const String& s);
4,String& replace(const String& t, const String& s);
5,子串替换成员函数的声明:
String& replace(const char* t, const char* s);
String& replace(const String& t, const char* s);
String& replace(const char* t, const String& s);
String& replace(const String& t, const String& s);
6,子串替换成员函数的定义:
1 /* 用 s 替换字符串中的 t */ 2 String& String::replace(const char* t, const char* s) 3 { 4 int index = indexOf(t); // 查找 t 的位置 5 6 if( index >= 0 ) // t 存在于当前的字符串中 7 { 8 remove(t); // 不要复制粘贴代码,要复用 9 insert(index, s); 10 } 11 12 return *this; 13 } 14 15 String& String::replace(const String& t, const char* s) 16 { 17 return replace(t.m_str, s); 18 } 19 20 String& String::replace(const char* t, const String& s) 21 { 22 return replace(t, s.m_str); 23 } 24 25 String& String::replace(const String& t, const String& s) 26 { 27 return replace(t.m_str, s.m_str); 28 }
6,从字符串中创建子串:
1,String sub(int i, int len) const;
1,以 i 为起点去长度为 len 的子串;
2,子串提取不会改变字符串本身的状态;
2,从字符串中创建子串成员函数的声明:
String sub(int i, int len) const; // 因为这里不会改变当前字符串状态,所以为 const 成员函数;
3,从字符串中创建子串成员函数的定义:
1 String String::sub(int i, int len) const // 查找当前字符串中第 i 个位置长度为 len 的字符串 2 { 3 String ret; 4 5 if( (0 <= i) && (i < m_length) ) 6 { 7 if( len < 0 ) len = 0; // 当小于零时候,不可能,要归一化到 0 8 if(len+i > m_length) len = m_length - i; // 只能够提取这么长的长度 9 10 char* str = reinterpret_cast<char*>(malloc(len + 1)); 11 12 if( str != NULL ) 13 { 14 strncpy(str, m_str + i, len); // 从 m_str + i 位置拷贝 len 长度的字符串,这里 m_str 是字符串起始位置 15 } 16 17 str[len] = '\0'; 18 ret = str; // 返回子串 19 20 free(str); 21 } 22 else 23 { 24 THROW_EXCEPTION(IndexOutOfBoundsException, "Parameter i is invaid ..."); 25 } 26 27 return ret; 28 }
7,本节课测试代码:
1 #include <iostream> 2 #include "DTString.h" 3 #include "malloc.h" 4 #include <cstring> 5 6 using namespace std; 7 using namespace DTLib; 8 9 int main() 10 { 11 String s = "ababax"; 12 String s1 = s- "bax"; 13 14 cout << s.str() << endl; 15 cout << s1.str() << endl; 16 17 s -= "ba"; 18 s -= s; 19 20 cout << "[" << s.str() << "]" << endl; 21 22 String s2 = "ababax"; 23 s2.replace("baba", "xyz"); 24 25 cout << s2.str() << endl; 26 27 String s3 = "ababax"; 28 String s4 = s3.sub(3, 2); 29 30 cout << s4.str() << endl; 31 32 return 0; 33 }
8,小结:
1,字符串类是工程开发中必不可少的组件;
2,字符串中应该包含常用字符串操作函数:
1,增:insert,operator +,...;
1,当前字符串增加;
2,删:remove,operator -,...;
1,当前字符串删除;
3,查: indexOf,...
1,当前字符串查找;
4,改:replace,...
1,当前字符串更改;