《C程序设计》(夏宝岚) 习题6.13 检查一个字符串中是否包含另一个字符串#include <stdio.h>#include <string.h>void main (){ int i = 0; int j = 0; int k = 0; /* 偏移量&&累计已经匹配的长度 */ int flag = 0; /* 是否有匹配的字符串标志位, 1为真, 0为假 */ char m[50]; char s[50]; printf("Mother string: "); gets(m); printf("Son string: "); gets(s); for(i = 0; i < (int)strlen(m); i++) { for(j = 0; j < (int)strlen(s); j++) { if(s[j] == m[i + k]) /* 若匹配则记录已经匹配的个数k */ k++; else /* 不匹配则跳出该重循环 */ break; } if(k == (int)strlen(s)) flag = 1; k = 0; /* 偏移量清零 */ } if(flag) printf("\n\"%s\" is subset of \"%s\"\n", s, m); else printf("\n\"%s\" is not subset of \"%s\"\n", s, m); }运行结果(VC)-匹配的情况:=================================================================Mother string: abcdefghijklmn↙Son string: defghi↙ "defghi" is subset of "abcdefghijklmn"=================================================================运行结果(VC)-未匹配的情况:=================================================================Mother string: abcdefghijklmn↙Son string: clkg↙ "clkg" is not subset of "abcdefghijklmn"=================================================================★ 思路:用二重循环,外层循环用变量i控制“母串”m[] 由第一个元素到最后一个元素。内层循环用变量j控制“子串”s[]。 比较子串的第一个元素与外层循环的每一个元素,若不相等,则跳出内层循环,重复上述过程; 若相等则需继续比较第二个元素,其内层循环用j容易控制,那此时外层循环的第二个元素如何控制呢? 开始想用i++控制,但如果在此内循环中多次i++后再次执行外循环时i的值已经不连续了(相对于外层),所以不可取。于是又引入变量k,它可以视为一个偏移量,这样内层连续比较时用m[i+k]来表示外层对应位置的字符就不会影响i的值了,而且这里k还有另一个重要作用:判断是否有匹配的串,当有一个字符匹配时就将其加1,若最终匹配,则这个k值应该与子串的长度相等,这便是判断的关键。例如子串长度为4,若与母串有匹配时,每次k加1,最终k值为4, 若中间遇到不匹配的字符,则停止比较,k的值也就不会达到子串长度4了。每次内循环结束后做一个判断,若k值等于子串长,则至少存在一个匹配的子串,将标志flag置1(初值为0),最后输出时只要判断标志flag是否为1(真)即可。 此程序仅仅对子串是否存在于母串中作了判断,其他细节如是否有多个匹配,从第几个字符开始匹配等未做处理。★ 网上查了下,关于这个字符串匹配的问题有专门的函数。而且在数据结构中还有专门的算法,看到了一个叫KMP的算法,有些地方还看不懂,有待进一步研究……。

评论