字符串匹配

字符串匹配或称为模式匹配,就是在主串String中查找模式串Pat。

1、最直接的方法就是调用库函数strstr():

char *Position;
Position = strstr(String, Pat);
strstr()函数用来检索子串在字符串中首次出现的位置,其原型为:
/**
 *【参数说明】s1为要检索的字符串,s2为要检索的子串。
 *【返回值】返回字符串s1中第一次出现子串s2的 地址;如果没有检索到子串,则返回NULL
 */
char *(strstr)( const char *s1, const char *s2 );
在《C标准库》中可以看到strstr的实现:

/* strstr function */
#include <string.h>

char *(strstr)(const char * s1, const char *s2)
{
	/* find fisrt occurrence of s2[] in s1[] */
	if (*s2 == '\0')
		return ((char *)s1);
	for (; (s1 = strchr(s1, *s2))!=NULL; ++s1)
	{
		/* match rest of prefix */
		const char *sc1, *sc2;
		for (sc1 = s1, sc2 = s2; ; )
			if (*++sc2 == '\0')
				return ((char*)s1);
			else if (*++sc1 != *sc2)
				break;
	}
	return NULL;
}
strstr的匹配是逐个比较模式串中的字符与主串里的字符,算法实现简单,容易理解,但效率不高。


2、对库函数strstr进行一些改进:

(1)如果strlen(Pat)大于主串剩下的串长,结束查找匹配;
(2)如果模式串Pat的第一个字符与主串Str中的字符匹配,然后将模式串中最后一个字符与主串中相应位置的字符比较,在很多情况下可以减少查找时间。

/**
 * 穷举搜索 : 逐个比较str与pat每个位置的字符
 * 返回pst在str中第一次匹配的位置,如果没匹配到返回-1。
 */
int completeSearch(char* str, char* pat)
{
	int i = 0, j = 0;
	int start;
	int strLength = strlen(str);
	int patLength = strlen(pat);
	for (start=0; start<=(strLength-patLength); start++)
	{
		i = start;
		j = 0;
		while (j<patLength && str[i]==pat[j])
		{
			i++;
			j++;
		}
		if (j==patLength)
			return start;
	}
	return -1;
}

/**
 * 先比较pat的首个字符如果与str中的匹配,再比较pat的最后一个字符
 *
 */
 int completeSearch_01(char* str, char* pat)
{
	int i = 0, j = 0;
	int start;
	int strLength = strlen(str);
	int patLength = strlen(pat);
	for (start=0; start<=(strLength-patLength); start++)
	{
		i = start;
		j = 0;
		if (str[i]==pat[j]) /* 先比较第一个字符 */
			if (str[i+patLength-1] == pat[patLength-1])	/* 在比较最后一个字符 */
			{
				j++;
				i++;
				while (j<patLength-1 && str[i]==pat[j])
				{
					i++;
					j++;
				}
				if (j==patLength-1)
					return start;	
			}
	}
	return -1;
}

上述模式匹配方法中最差的情况下时间复杂度依旧是O(mn);其中m=strlen(Str), n=strlen(Pat)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值