字符串匹配/模糊匹配(查找/模糊查找)的算法

这个还从一次的华为机试的题目说起,题目大概如下

//问题描述:输入,一个待匹配的字符串str1,串长小于20,一个匹配字符串str2,串长小于100

//将str1中的字符串在str2中匹配
//str1里面包含有“*”,“?”替代字符,一个“?”可以替代任何一个数字或者字母,“*”可以替代几个连续的数字和字母
//现在在str2中找到和字符串str1匹配的所有位置,输出第一个字母的位置的值index
//例如:
//输入:ab?12*cd
//  qaxabc12xrcdwew       
//输出:4

中间还要穿插一个故事,初中的时候我用过好记星e600,不知道是好记星的第几代产品,应该是非常非常早的产品了,其中有一个单词匹配的算法,它的规则和这个非常像,当你不确定自己输入单词是什么的时候,若忘记了一个字母,就在这个位置用"?"来代替,忘记了几个字母,就用“*”来代替,它会帮你查找词库,重新搜索下单词。


下面给出我写的代码。

//*********************************************************
//时间:2014年10月5日
//作者:RenTaorui
//问题描述:输入,一个待匹配的字符串str1,串长小于20,一个匹配字符串str2,串长小于100
//str1里面包含有“*”,“?”替代字符,一个“?”可以替代任何一个数字或者字母,“*”可以替代几个连续的数字和字母
//现在在str2中找到和字符串str1匹配的所有位置,输出第一个字母的位置的值index
//例如:
//输入:ab?12*cd
//		qaxabc12xrcdwew        
//输出:4
//*********************************************************
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

	//算法演示
	//举例如下
	//   q  a  x  a  b  c  1  2  x  r  c  d  w  e  w
	//a  0  2  0  4  0  0  0  0  0  0  0  0  0  0  0  
	//b  0  0  0  0  5  0  0  0  0  0  0  0  0  0  0
	//?  0  0  0  0  0  6  0  0  0  0  0  0  0  0  0
	//1  0  0  0  0  0  0  7  0  0  0  0  0  0  0  0
	//2  0  0  0  0  0  0  0  8  0  0  0  0  0  0  0
	//*  0  0  0  0  0  0  0  0  9  9  9  9  9  9  9
	//c  0  0  0  0  0  6  0  0  0  0  10 0  0  0  0
	//d  0  0  0  0  0  6  0  0  0  0  0  11 0  0  0

	//答案 11-len("ab?12*cd")+1=4

int main()
{
	char str1[21],str2[101];
	int calc_arr[20][101]={0};
	int flag=0;
	int len1,len2;
	int i ,j ,k;
	scanf("%s",str1);
	scanf("%s",str2);
	len1=strlen(str1);
	len2=strlen(str2);
	for(j=0;j<len2;j++)
	{
		if(str1[0]==str2[j])
		{
			calc_arr[0][j]=j+1;
		}
	}//第一行先要初始化,在第一个字母匹配的时候,标记出数字,数字的值为当前第一个字母在串中的位置
	for(i=1;i<len1;i++) 
	{
		for(j=i;j<len2;j++)
		{
			if(str1[i]=='?')
			{
				if(calc_arr[i-1][j-1]!=0)
				{
						calc_arr[i][j]=calc_arr[i-1][j-1]+1;
				}
			}
			else if(str1[i]=='*')
			{
				calc_arr[i][j]=calc_arr[i-1][j-1]==0?calc_arr[i][j-1]:calc_arr[i-1][j-1]+1;
			}
			else if(str1[i]==str2[j])
			{
				if(calc_arr[i-1][j-1]!=0)
				{
					calc_arr[i][j]=calc_arr[i-1][j-1]+1;
				}
			}
		}
	}
	for(j=0;j<len2;j++)
	{
		if(calc_arr[len1-1][j]!=0)
		{
			printf("%d\n",calc_arr[len1-1][j]-len1+1);
			flag=1;
		}
	}
	if(flag==0)
	{
		printf("No match!\n");
	}
	system("pause");
	return 0;
}
这段代码能够表现出的一个好处是能够在代码的过程中很容易找出常用方法难判断的地方
input
123*123
jh123hjk123jk123j
output
3
9
但是在空间复杂度上,此方法只用到了所创建空间的一半,所以贴出来,还希望大家能有什么好的方法好好讨论。相信网上现在已经有很多相同类型的题目的代了。

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值