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

实现一个挺高级的字符匹配 算法:
给一串很长字符串 ,要求找到符合要求 的字符串,例如目的串: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++;
	}
}


fuck
sIfuckyoufsdfuascask
sI****youfsd**as*as*


但是,我们发现一个Bug

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

ab
aaaabb
aaa**b

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值