字符串匹配
2016-01-22 10:39
316 查看
字符串匹配或称为模式匹配,就是在主串String中查找模式串Pat。
1、最直接的方法就是调用库函数strstr():
char *Position;
Position = strstr(String, Pat);
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)。
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)。
相关文章推荐
- Android之获取手机上的图片和视频缩略图thumbnails
- android string.xml文件中的整型和string型代替
- Android java 与 javascript互访(相互调用)的方法例子
- 如何组织构建多文件 C 语言程序(二)
- android上改变listView的选中颜色
- String.intern
- 如何写好 C main 函数
- Prototype源码浅析 String部分(二)
- Ruby中的String对象学习笔记
- 修复mysql数据库
- Lua和C语言的交互详解
- PostgreSQL ERROR: invalid escape string 解决办法
- nodejs中的fiber(纤程)库详解
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- C语言编程中统计输入的行数以及单词个数的方法