本文源自《编程之美》3.5 最短摘要生成一课。
题意:在一个字符串中,找一些目标字符串集合,找到包含所有目标字符串的最小连续子串。题目虽然叫做“最短摘要生成”,但和实际上的搜索snippet的计算还有较大差距。
解法:采用了“双指针”策略,其思想在很多算法设计中都有价值。思想是:开始两个指针都指向缓冲区头部,尾指针向后扫描,直到头指针和尾指针中间包含了全部的关键字;那么头指针向后移动,直到包含全部关键字的这个条件失败。这是截取字符串并和已取得的最小字符串比较,如果小则替换。
下面是我的代码
#include <iostream> #if 0 #include <hash_map.h> //因为hash_map暂不为cpp标准,所以没法<hash_map> #else #include <tr1/unordered_map> #define hash_map std::tr1::unordered_map #endif using namespace std; void findMinAbstract(char* w, int wLen, char* q, int qLen){ //[begin, end]双指针 int begin=0; int end=-1; //最短摘要 int minLen=wLen+1; //最短摘要长度 int minBegin; //最短摘要开始 int minEnd; //最短摘要结束 hash_map<char, bool> qHashMap; //需要找的关键字 for(int i=0;i<qLen;i++){ qHashMap[q[i]]=true; } hash_map<char, int> qFoundCnt; //统计找到关键字的次数 int qFoundNum=0; //已经找到的关键字个数 while(true){ //在当前状态[begin, end]: 还没找到所有关键字 ,后指针后移 while(qFoundNum<qLen && end<=wLen-1){ end++; if(qHashMap[w[end]]==true){//找到关键字 if(qFoundCnt[w[end]]==0){//以前找到过 qFoundCnt[w[end]]=1; qFoundNum++; }else{ //以前未找到过 qFoundCnt[w[end]]++; } } } //在当前状态[begin, end]: 已经找到所有关键字,前指针后移 while(qFoundNum==qLen && begin<=end){ if(end-begin+1<minLen){ minLen=end-begin+1; minBegin=begin; minEnd=end; } //前指针后移:去掉 w[begin] if(qHashMap[w[begin]]==true){ if(qFoundCnt[w[begin]]>1){ qFoundCnt[w[begin]]--; }else if(qFoundCnt[w[begin]]==1){ qFoundCnt[w[begin]]=0; qFoundNum--; } } begin++; } if(end>=wLen) break; } //显示最短摘要 for(int i=0;i<wLen;i++){ cout<<w[i]; }cout<<endl; for(int i=0;i<wLen;i++){ if(i==minBegin){ cout<<"b"; }else if(i==minEnd){ cout<<"e"; }else{ cout<<" "; } }cout<<endl; cout<<"minLen = "<<minLen<<endl; } int main(){ char* w="abbbbbcaaadebmmmmdcfg"; int wLen=21; char* q="bd"; int qLen=2; findMinAbstract(w, wLen, q, qLen); return 0; }
效果:
相关推荐
线性表是最基本的数据结构之一,通过连续的内存位置或链式结构存储元素,支持增删查改操作。 **3.2 线性表的顺序存储与实现**:利用数组实现,访问速度快,但插入删除效率较低。 **3.3 线性表的链式存储与实现** ...
- 最小生成树是在连通加权无向图中寻找一棵包含所有顶点的生成树,使得该树的所有边的权重之和最小。 **4.9 最短距离** - **单源最短路径** - Dijkstra算法和Bellman-Ford算法是求解单源最短路径问题的经典算法...
以上内容覆盖了软考中级数据库思维导图中提到的主要知识点,从计算机硬件到软件编程语言的基础,再到数据结构与算法等方面进行了详细介绍。这些知识点对于理解和掌握数据库管理及应用开发具有重要的意义。
在《数据结构与算法 JAVA 版》这本书中,第一章主要介绍了Java编程语言的基础知识以及其面向对象的特点。 - **1.1 Java语言基础知识** - **1.1.1 基本数据类型及运算**:这部分内容涵盖了Java中的基本数据类型,如...
- **Strategy接口**:可能涉及策略模式,虽然这个概念通常与设计模式有关,但在这里可能是为了说明如何根据不同需求选择不同的线性表实现策略。 ##### 3.2 线性表的顺序存储与实现 - 详细介绍顺序存储方式下的...
- **Strategy接口**:解释策略模式的概念,并讨论其在Java编程中的应用。 ##### 3.2 线性表的顺序存储与实现 - 讨论顺序存储的原理、优点(如访问速度快)和缺点(如插入删除操作效率低)。 ##### 3.3 线性表的...
C3.5 程序员定义的异常类 232 第7章 实现ADT栈 235 7.1 基于数组的实现 236 7.2 基于链表的实现 239 7.3 在实现中使用异常 243 第8章 列表 247 8.1 指定ADT列表 248 8.2 使用列表操作 252 8.3 ADT列表的模板...
3.5 间接寻址 99 3.5.1 基本概念 99 3.5.2 操作 100 3.6 模拟指针 102 3.6.1 SimSpace的操作 103 3.6.2 采用模拟指针的链表 106 3.7 描述方法的比较 110 3.8 应用 111 3.8.1 箱子排序 111 3.8.2 基数排序 116 3.8.3 ...
本章节介绍了栈与队列这两种特殊的数据结构,并对其在实际编程中的应用进行了详细的解析。 **4.1 栈** - **栈的定义及抽象数据类型** - 栈的概念与特点 - 栈的抽象数据类型定义 - **栈的顺序存储实现** - 顺序...
- 在处理线性表时,可以使用不同的策略来实现特定功能。 **3.2 线性表的顺序存储与实现** - **3.2.1 顺序存储** - 顺序存储通过数组来实现线性表。 - 元素按顺序排列,支持快速随机访问。 - **3.2.2 实现** -...
### JAVA语言版数据结构与算法知识点详解 ...这些知识点覆盖了Java编程的基础知识、面向对象的特性、数据结构的理论与实践、算法的设计与分析等多个方面,对于学习Java编程和深入理解数据结构与算法至关重要。
- 递归是一种函数调用自身的编程技巧。 - **5.1.2 递归的实现与堆栈** - 讨论递归如何利用系统栈实现。 **5.2 基于归纳的递归** - **5.3 递推关系求解** - **5.3.1 求解递推关系的常用方法** - 包括特征方程...
- **最小生成树**:对于一个连通的无向图,其生成树是一棵包含所有顶点且没有回路的子图。 **4.9 最短距离** - **单源最短路径**:Dijkstra算法和Bellman-Ford算法。 - **任意顶点间的最短路径**:Floyd-Warshall...
- **双链式存储结构** - 结合了链表和双向链表的优点,适用于复杂的图操作。 ##### 4.6 图ADT实现设计 - 介绍如何设计图的ADT实现。 ##### 4.7 图的遍历 - **深度优先搜索** - 从根节点开始,尽可能深地搜索树...
- **基础知识:** 线性表作为数据结构的基础,是本设计的核心内容之一。它不仅是最基本的线性结构,也是进一步学习其他复杂数据结构的基础。 - **目标:** 使用单链表的操作实现通讯录系统的管理功能。 - **具体需求...
会到keil c51 生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑, 容易理解。在开发大型软件时更能体现高级语言的优势。 Keil C51 可以完成编辑、编译、连接、调试、仿真等整个开发流程。开发人 员可用IDE...
- Strategy模式允许在运行时改变对象的行为,这里可能是为了定义线性表的不同操作策略。 **3.2 线性表的顺序存储与实现** - **3.2.1 单链表** - 单链表是一种通过节点之间的链接来表示数据的线性结构。 - 每个...