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

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

//问题描述:输入,一个待匹配的字符串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 但是在空间复杂度上,此方法只用到了所创建空间的一半,所以贴出来,还希望大家能有什么好的方法好好讨论。相信网上现在已经有很多相同类型的题目的代了。



    原文作者:查找算法
    原文地址: https://blog.csdn.net/ruixuefengnian/article/details/39852749
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞