C++ KMP算法详解与指针问题实例
在C++编程中,KMP(Knuth-Morris-Pratt)算法是一种重要的字符串匹配算法,它用于在一个文本串中查找指定模式串的出现位置,相较于传统的暴力搜索,KMP算法具有更高的效率,特别是对于那些重复较少的模式串。本文将结合C++模板代码来深入解析KMP算法的工作原理及其实现。 首先,了解C++中的指针漂移问题。在C++中,当我们试图通过指针类型转换来访问不同类型的成员时,可能会遇到指针漂移的问题。例如,在代码示例中,`AB*pab`是一个`AB`类型的指针,但通过`(A*)pab`和`(B*)pab`分别将其强制转换为`A`和`B`类型的指针,实际上指向的是`AB`对象的公共部分。这种操作可能导致内存地址的偏移,因为`AB`类继承自`A`和`B`,所以`pab`可能同时拥有`A`和`B`的成员变量,而不仅仅是其中一个。在访问成员时,如果仅通过基类指针进行,可能会访问到意外的数据。 接着,文章介绍了如何使用`void*`类型转换来间接访问`AB`对象,通过`std::vector`容器插入`pab`并间接获取其地址。这种做法虽然可以避免直接类型转换带来的问题,但还是需要注意潜在的类型不安全,因为`void*`不能直接进行类型检查。在访问`A`类成员时,通过间接转换得到的指针可以正确访问`A`的成员,如`pa->a`,但在处理其他类型时可能存在隐患。 然后,KMP算法被提及,但没有提供具体的代码实现。KMP算法的核心是预处理模式串,生成一个部分匹配表(Partial Match Table, PMT),使得在搜索过程中无需回溯,提高了匹配效率。然而,由于篇幅限制,这部分内容并未详细展开,读者可能需要参考其他资源来学习完整的KMP算法实现。 最后,代码中包含了一些C++库的使用,如`#include<stdio.h>`、`#include<vector>`以及`std::vector`和`std::namespace`的引入。这展示了在实际编程中如何利用标准库进行内存管理和容器操作。 本篇文章主要关注C++中的指针操作和类型转换,特别提到了在处理多态性和复杂类型时可能出现的问题,并简要提及了KMP算法在字符串匹配中的应用。对于想深入了解C++指针和高级算法的程序员来说,本文是一个不错的起点,但若想全面掌握KMP算法,还需要进一步学习和实践。
最近我们在工作中碰到一个奇怪的问题,最后确定是多继承引起的C++指针漂移,跟C++对象模型有关。示意如下:
class A {...}; class B{...}; class AB : public B, public A {...} ... AB *pab = new AB(); A* pa = (A*)pab; B* pb = (B*)pab; 这时候你发现pa和pb的值是不一样的!它们中有一个跟pab是相等的,而另外一个产生了偏移。如果把AB的声明中A和B的顺序调换一下,则产生偏移的指针也会变为另外一个。
为了确定这是编译器做了转换的缘故,利用void指针愚弄编译器:
void *pv = (void*)pab; pa = (A*)pv; 这时候pa的值倒是跟pab相等了,然而指向了错误的地方。从pab到pa的转换,依赖于路径的选择,让人不是很放心。还不知道把指针放入容器中再取出来,会不会出错。当然,上面使用了强制类型转换,在良好的程序中应该避免。如果只有隐式转换,可以得到正确的结果:
std::vector<A*> v; //implicit type conversion v.insert(v.begin(), pab); void *pv = v[0]; pa = (A*)pv; 以下程序使用Cygwin/g++b编译通过:
#include <stdio.h> #include <vector> class A { public: int a; }; class B { public: int b; }; class AB : public B, public A { public: int ab; }; int main(int argc, char **argv) { AB *pab = new AB(); pab->ab = 1; pab->b = 2; pab->a = 3; A* pa = (A*)pab; B* pb = (B*)pab; printf( "AB: %p\n" \ " A: %p\n" \ " B: %p\n", pab, pa, pb); std::vector<A*> v; //implicit type conversion v.insert(v.begin(), pab); void *pv = v[0]; pa = (A*)pv; printf("pv is %p\npa is %p\npab %s pv\n", pv, pa, (pab == pv) ? "==" : "!="); printf("A.a is %d\n", pa->a); //forced type conversion pv = (void*)pab; pa = (A*)pv; printf("Now A.a is %d\n", pa->a); } 运行结果:
AB: 0x6b01f0 A: 0x6b01f4 B: 0x6b01f0 pv is 0x6b01f4 pa C++编程语言中的模板应用是一个比较复杂的应用技术,我们今天就先从C++ kmp算法模板的基本应用开始学习,从而加深我们对这方面知识的认识程度,方便将来的应用,提高编程效率。
在使用的时候加上这两行代码就行了
#include < vector> using namespace std;
C++ kmp算法模板参数说明
const T *source 待匹配的字符串
TL sourceLen 待匹配字符串的长度
const T *pattern 模式串
TL 模式串长度
下载后可阅读完整内容,剩余2页未读,立即下载
- 粉丝: 3
- 资源: 123
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- zlib-1.2.12压缩包解析与技术要点
- 微信小程序滑动选项卡源码模版发布
- Unity虚拟人物唇同步插件Oculus Lipsync介绍
- Nginx 1.18.0版本WinSW自动安装与管理指南
- Java Swing和JDBC实现的ATM系统源码解析
- 掌握Spark Streaming与Maven集成的分布式大数据处理
- 深入学习推荐系统:教程、案例与项目实践
- Web开发者必备的取色工具软件介绍
- C语言实现李春葆数据结构实验程序
- 超市管理系统开发:asp+SQL Server 2005实战
- Redis伪集群搭建教程与实践
- 掌握网络活动细节:Wireshark v3.6.3网络嗅探工具详解
- 全面掌握美赛:建模、分析与编程实现教程
- Java图书馆系统完整项目源码及SQL文件解析
- PCtoLCD2002软件:高效图片和字符取模转换
- Java开发的体育赛事在线购票系统源码分析