三十九、字符串类的创建(上)
1、历史遗留问题
- C语言不支持真正意义上的字符串
- C语言用字符数组和一组函数实现字符串操作
- C语言不支持自定义类型,因此无法获得字符串类型
- 从C到C++的进化过程引入了自定义类型
- 在C++中可以通过类完成字符串类型的定义
- 问题:
C++中的原生类型系统是否包含字符串类型?
没有,通过标准库。
2、DTLib 中字符串类的设计
3、DTLib 中字符串类的实现
4、实现时的注意事项
- 无缝实现 String对象与char*字符串的互操作
- 操作符重载函数需要考虑是否支持const版本
- 通过C语言中的字符串函数实现String的成员函数
5、编程实验:字符串类的实现
String.h
String.cpp
6、小结
- C /C++语言本身不支持字符串类型
- C语言通过字符数组和一组函数支持字符串操作
- C++通过自定义字符串类型支持字符串操作
- 字符串类型通过C语言中的字符串函数实现
四十、字符串类的创建(下)
1、字符串类中的常用成员函数
2、重载数组访问操作符[]
- char& operator [] (int i);
- char operator [] (int i) const;
- 注意事项
- 当i的取值不合法时,抛出异常
- 合法范围:( 0<=i ) && ( i < m_length )
- 当i的取值不合法时,抛出异常
3、判断是否以指定字符串开始或结束
- bool startWith(const char* s) const;
- bool startWith(const String& s) const;
- bool endOf(const char* s) const;
- bool endOf(const String& s) const;
4、在指定位置处插入字符串
- String& insert(int i, const char* s);
- String& insert(int i, const String& s);
5、去掉字符串两端的空白字符
- String & trim();
6、编程实验:常用成员函数的实现
string.h
string.cpp
7、To be continued ...
思考:
如何在目标字符串中查找是否存在指定的子串?
四十一、KMP 子串查找算法
1、问题
如何在目标字符串S中,查找是否存在子串P ?
2、朴素解法
3、朴素解法的一个优化线索
4、示例
5、伟大的发现
- 匹配失败时的右移位数与子串本身相关,与目标串无关
- 移动位数 = 已匹配的字符数 - 对应的部分匹配值
- 任意子串都存在一个唯一的部分匹配表
6、部分匹配表示例
7、问题:部分匹配表是怎么得到的?
- 前缀
- 除了最后一个字符以外,一个字符串的全部头部组合
- 后缀
- 除了第一个字符以外,一个字符串的全部尾部组合
- 部分匹配值
- 前缀和后缀最长共有元素的长度
示例: ABCDABD
8、问题:怎么编程产生部分匹配表?
- 实现关键
- PMT[1] = 0(下标为0的元素匹配值为0)
- 从2个字符开始递推(从下标为1的字符开始递推)
- 假设PMT[n] = PMT[n-1]+1(最长共有元素的长度)
- 当假设不成立,PMT[n]在PMT[n-1]的基础上减小