算法习题33:字符串匹配(和谐文字)

来源:互联网 发布:简述信息和数据的关系 编辑:程序博客网 时间:2024/05/21 17:16
实现一个挺高级的字符匹配算法:
给一串很长字符串,要求找到符合要求的字符串,例如目的串:123
1******3***2 ,12*****3这些都要找出来

其实就是类似一些和谐系统。。。。。

--------------------------------------------------------------------

(再次申明:这些题目均来自:http://bbs.csdn.net/topics/350118968)

这道题网络上也有很多讨论,很多人把它和“给一个很长的字符串str, 还有一个字符集比如{a,b,c},找出str包含{a,b,c}的最短子串,要求O(n)。”这道题相比较,给出一个更好的答案。

随大流,我也这么弄把,因为这道题确实能够进一步说明问题。。。

方法1:

当然就是遍历,我们假设模式有m个字符,待匹配串有n个字符,那么我们一个个遍历n,匹配上了模式则记录下来,最后处理。。

这个时间复杂度就是O(m*n)

这道题有点像:http://blog.csdn.net/ylf13/article/details/12565419这篇博文的题目

所以,有一个方法很快就会浮现出来,不是可以用哈希表么,这个查找起来多块,是的,可以让查找速度从O(m)降到O(1) 

http://blog.csdn.net/ylf13/article/details/12713509我这里实现了哈希表的一个简单案例

方法二:哈希表提高速度

我们这里如果仅仅是要找到需要的字符串,是很容易的,但是如果要找出最近的才需要删除呢?

比如:模式love   字符串是:Ilolloveyou我们希望和谐的是Ilol****you 不是I**llo**you这种,所以需要实现最短的

我们这里需要借助一个哈希表来记录当前模式字符最新的位置在哪里,后面删除的时候用上就好了

所以,match_hashtable这里记录的是模式对应最近的字符位置

源方法可以参见:http://blog.csdn.net/cxllyg/article/details/7595878

//============================================================================// Name        : StrMatch.cpp// Author      : YLF// Version     :// Copyright   : Your copyright notice// Description : Hello World in C++, Ansi-style//============================================================================#include <iostream>#include <string.h>#include <stdio.h>using namespace std;void StrMatch(char* pattern, char* str);void ProcessStr(char* pattern, char* str, char* match_hashtable);int main() {char pattern[255];char str[255];cin>>pattern>>str;StrMatch(pattern, str);cout<<str;return 0;}void StrMatch(char* pattern, char* str){char pattern_hashtable[255];char match_hashtable[255];int i = 0, count = 0;char *p = str;memset(pattern_hashtable,-1,255);memset(match_hashtable,-1,255);for(i=0;i<strlen(pattern);i++)pattern_hashtable[pattern[i]] = 1;while(*p != '\0'){if(pattern_hashtable[(int)*p] == 1){//是我们要找的字符if(match_hashtable[(int)*p] != -1){//已经找到过,我们这里为了只屏蔽最短的字符串,所以更新下距离match_hashtable[(int)*p] = (p-str);}else{match_hashtable[(int)*p] = (p-str);count++;//找到了整个匹配上的字符串了if(count == strlen(pattern)){ProcessStr(pattern, str, match_hashtable);//清除数据count = 0;memset(match_hashtable,-1,255);}}}p++;}}void ProcessStr(char* pattern, char* str, char* match_hashtable){while(*pattern != '\0'){str[match_hashtable[(int)*pattern]] = '*';pattern++;}}


fucksIfuckyoufsdfuascasksI****youfsd**as*as*


但是,我们发现一个Bug

这种记录方法只能和谐掉相邻近的字符串,却无法和谐了远点的字符串了,例如

abaaaabbaaa**b

我们这里的match_hashtable[]不具有记忆能力,只能记录一个最新位置

所以可以采用链表方式来记录相关字符出现的位置,这就具有记忆能力了

原创粉丝点击