其实,模式匹配的穷举法也可以改进,下面是经过改进后的代码。
【Improve Version】
其中StrMatchImp()函数是经过改进后的函数。
/* 本程序测试字符串的各种处理函数和操作 */ #include <stdio.h> #include <stdlib.h> #include <string.h> //******************************************************0 // 定义用户数据类型 typedef long int LINT; typedef enum {FALSE,TRUE} BOOL; //******************************************************1 //******************************************************0 int StringMatch(char* String,char* subString,int StartIndex); int StringMatchRecall(char* String,char* subString,int StartIndex); int StrMatchImp(char* string,char* subString,int startIndex); int main(int argc,char* argv[]) { int x; x=StringMatch("abcdefghijklmn","lm",0); printf("%d \n",x); x=StringMatchRecall("abcdefghijklmn","x",0); printf("%d \n",x); x=StrMatchImp("abcdefghijklmn","lm",0); printf("%d \n",x); getchar(); getchar(); return 0; } //******************************************************1 //******************************************************0 /* 函数功能: 模式匹配朴素算法:双循环 函数原型: int StringMatch(char* String,char* subString,int StartIndex) 函数参数: char* String:字符串 char* subString:模式字符串 int StartIndex:搜索开始索引 返回值: 如果匹配成功,则返回模式字符串在字符串中开始的首地址; 如果匹配失败,则返回-1 异常: 无 */ int StringMatch(char* String,char* subString,int StartIndex) { int i, j; int StrLen, SubStrLen; StrLen=strlen(String); SubStrLen=strlen(subString); //检查指针有效性和空串 //其实这里也可以不检测 StartIndex>strlen(String)-strlen(subString) if( !String || !subString || !String[0] || !subString\ || StartIndex > StrLen-SubStrLen\ ) return -1; for(i=StartIndex;i<= StrLen - SubStrLen ;i++) { for(j=0; j < SubStrLen ;j++) { if(String[i+j] - subString[j]) break; } if(j==SubStrLen) //这么判断因为要结束循环正好相等 return ++i; //这个地方不能用i++ } return -1; } //******************************************************1 //******************************************************0 /* 函数功能: 模式匹配朴素算法:单循环回溯 函数原型: int StringMatchRecall(char* String,char* subString,LINT StartIndex) 函数参数: char* String:字符串 char* subString:模式字符串 int StartIndex:搜索开始索引 返回值: 如果匹配成功,则返回模式字符串在字符串中开始的首地址; 如果匹配失败,则返回-1 异常: 无 */ int StringMatchRecall(char* String,char* subString,int StartIndex) { int i, j; int StrLen, SubStrLen; StrLen=strlen(String); SubStrLen=strlen(subString); //检查指针有效性和空串 //其实这里也可以不检测 StartIndex>strlen(String)-strlen(subString) if( !String || !subString || !String[0] || !subString\ || StartIndex > StrLen-SubStrLen\ ) return -1; i=StartIndex; j=0; while( i < StrLen ) { if(String[i] == subString[j] ) { ++j; ++i; } else { i=i-j+1; //回溯 j=0; } if(j==SubStrLen) return i-j+1; } return -1; } //******************************************************1 //******************************************************0 /* 函数功能: 字符串模式匹配穷举法:改进版 函数原型: int StrMatchImp(char* string,char* subString,int startIndex) 函数参数: char* string: 字符串 char* subString:模式字符串 int startIndex:搜索首索引 返回值: 如果匹配成功,返回匹配首字符的index+1 异常: 无 */ int StrMatchImp(char* string,char* subString,int startIndex) { int i, j; int StrLen, SubStrLen; StrLen=strlen(string); SubStrLen=strlen(subString); //检查指针有效性和空串 //其实这里也可以不检测 StartIndex>strlen(String)-strlen(subString) if( !string || !subString || !string[0] || !subString\ || startIndex > StrLen-SubStrLen\ ) return -1; for(i=startIndex;i<= StrLen - SubStrLen ;i++) { for(j=0; j < SubStrLen ;j++) { if( string[i+j] - subString[j]) break; else { //如果模式的首字符subString[0]已经匹配, //则判断最后一个字符subString[SubStrLen-1]是否匹配 //依次类推,这样最好的时候可以提高效率, //最差的时候还是需要O(m*n) if(string[i+SubStrLen-1-j] - subString[SubStrLen-1-j]) break; } } if(j==SubStrLen) //这么判断因为要结束循环正好相等,也可用subString[j]=='\0' return ++i; //这个地方不能用i++ } return -1; } //******************************************************1 //******************************************************0 /* 函数功能: 求解字符串本身的从尾节点往头节点方向子串中最大的匹配串 函数原型: int GetMaxSubStringLen(const char* string) 函数参数: const char* String:字符串 返回值: 如果有的话则返回最大长度,否则就返回-1 异常: 无 */ int GetMaxSubStringLen(const char* string) { return -1; } //******************************************************1
程序运行结果如下所示:
这个东西还是有很复杂啊,哎,需要继续学习学习。