标签:
今天做了一道题,要用判断一个字符串是否是另一个字符串的子串,于是查了一下strstr的实现。
代码如下:
1 char *strstr(const char*s1,const char*s2) 2 { 3 const char*p=s1; 4 const size_t len=strlen(s2); 5 for(;(p=strchr(p,*s2))!=0;p++) 6 { 7 if(strncmp(p,s2,len)==0) 8 return (char*)p; 9 } 10 return(0); 11 }
从代码可以分析出,strstr的时间复杂度是O(n2)的(因为strncmp是O(N)的),所以对长字符串匹配子串上可以采用kmp算法来提高效率(时间复杂度为O(m+n)),这里翻出了自己以前写的kmp算法的接口放到这里和大家分享一下,之前我也写过一篇关于kmp匹配子串的一篇文章,也可以去看一下,欢迎纠正错误和分享经验。
1 #include <string.h> 2 #include <stdio.h> 3 4 #define LIB_MATCH_NUM 5 5 #define LIB_STRING_LEN 40 6 7 char lib_match[LIB_MATCH_NUM][LIB_STRING_LEN] = 8 { 9 "www.baidu.comw", 10 "www.google.com", 11 "www", 12 "baidu.com", 13 "lualu", 14 }; 15 16 int lib_match_len[LIB_MATCH_NUM]; 17 18 int lib_match_next[LIB_MATCH_NUM][LIB_STRING_LEN + 1] = {0}; 19 20 21 void get_next(); 22 23 void lib_match_init() 24 { 25 memset(lib_match_len,0,sizeof(lib_match_len)); 26 int i; 27 for(i = 0; i < LIB_MATCH_NUM; i++) 28 { 29 lib_match_len[i] = strlen(lib_match[i]); 30 } 31 32 get_next(); // init next array 33 } 34 35 void get_next() 36 { 37 int i,j,k; 38 39 for(i = 0; i < LIB_MATCH_NUM; i++) 40 { 41 42 lib_match_next[i][0] = 0; 43 lib_match_next[i][1] = 0; 44 45 k = 0; //point to the last next[j] 46 int len = lib_match_len[i]; 47 48 for( j = 1; j < len; j++) 49 {//j start from 1 because next start from 2 50 while(k > 0 && lib_match[i][j] != lib_match[i][k]) 51 { 52 k = lib_match_next[i][k]; 53 } 54 55 if(lib_match[i][j] == lib_match[i][k]) 56 {//s[j] == s[next[k]] next[i+1] = next[i] +1 57 k++; 58 } 59 60 lib_match_next[i][j+1] = k; 61 } 62 63 } 64 65 } 66 67 int lib_search(char *orignal,int len) 68 { 69 int i,j,k; 70 71 for(i = 0; i < LIB_MATCH_NUM; i++) 72 { 73 char *tmp = orignal; // match each model need to start from the first 74 k = 0; // k start from the last next array 75 76 for(j = 0; j < len; j++) 77 { 78 79 while( k > 0 && tmp[j] != lib_match[i][k]) 80 { 81 k = lib_match_next[i][k]; 82 } 83 84 if(tmp[j] == lib_match[i][k]) 85 { 86 k++; 87 } 88 89 if(k == lib_match_len[i]) 90 { 91 printf("match the model string %d : %s\n", i,lib_match[i]); 92 printf("match at the position :%d\n\n", j - lib_match_len[i] + 1); 93 94 // here can return the i to know which model string have been matched 95 96 k = lib_match_next[i][k]; //to match another this model string 97 } 98 99 } 100 101 } 102 103 return 0; 104 } 105 106 void print_next() 107 { 108 int i,j; 109 110 for(i = 0; i < LIB_MATCH_NUM; i++) 111 { 112 printf("model string : %s \n",lib_match[i]); 113 printf("next array:"); 114 for(j = 0; j < lib_match_len[i]+1;j++) 115 { 116 printf(" %d",lib_match_next[i][j]); 117 } 118 printf("\n\n"); 119 } 120 } 121 122 123 int main() 124 { 125 char orignal[40]; 126 127 lib_match_init(); 128 129 print_next(); 130 131 while(1) 132 { 133 134 scanf("%s",orignal); 135 136 if(strcmp(orignal,"0") == 0) 137 { 138 return 0; 139 } 140 141 lib_search(orignal,strlen(orignal)); 142 } 143 144 return 0; 145 146 }
Linux GCC下strstr的实现以及一个简单的Kmp算法的接口
标签:
原文地址:http://www.cnblogs.com/daimadebanyungong/p/5258631.html