一、使用strstr函数进行判断
#include<stdio.h> #include<string.h> int main() { char str1[50],str2[50]; printf("请输入字符串1:\n"); scanf("%s",str1); printf("请输入字符串2:\n"); scanf("%s",str2); if(strstr(str1,str2)!=NULL) printf("字符串2是字符串1的子串\n"); else printf("字符串2不是字符串1的子串\n"); return 0; }
在C语言中,可以使用strstr函数来判断一个字符串是否包含另一个字符串。strstr函数的使用方法为:strstr(字符串1,字符串2),函数返回值为字符串2在字符串1中第一次出现的地址。如果字符串2不是字符串1的子串,则函数返回NULL。
在上面的代码中,通过scanf函数获取了两个字符串str1和str2,并使用strstr函数来进行判断。如果返回的地址不为NULL,则表示字符串2是字符串1的子串;反之则不是。
二、使用循环遍历判断
#include<stdio.h> #include<string.h> int main() { char str1[50],str2[50]; int i,j,flag=0; printf("请输入字符串1:\n"); scanf("%s",str1); printf("请输入字符串2:\n"); scanf("%s",str2); for(i=0;i<strlen(str1);i++) { if(str1[i]==str2[0]) { flag=1; for(j=0;j<strlen(str2);j++) { if(str1[i+j]!=str2[j]) { flag=0; break; } } if(flag==1) break; } } if(flag==1) printf("字符串2是字符串1的子串\n"); else printf("字符串2不是字符串1的子串\n"); return 0; }
除了使用strstr函数之外,我们也可以使用循环来遍历字符串中的每个字符,并判断是否符合子串。在上面的代码中,我们首先通过scanf函数获取了两个字符串str1和str2,并使用两个循环变量i和j分别对字符串1和字符串2进行遍历。
如果字符串1中的某个字符与字符串2的第一个字符相同,我们就认为找到了一个可能的子串,并使用flag变量进行标记。接着,在内层循环中,我们依次比较字符串1中与找到的字符串2的第1个字符相同的字符是否也与字符串2中对应位置的字符相同。如果比较过程中有任何一个字符不相同,就说明找到的子串是错误的。最后,根据flag的取值来判断字符串2是否是字符串1的子串。
三、使用递归函数判断
#include<stdio.h> #include<string.h> int match(char *s1,char *s2) { if(*s1=='\0'||*s2=='\0') return 0; if(*s1==*s2) return match(s1+1,s2+1)+1; else return 0; } int main() { char str1[50],str2[50]; int i,result=0; printf("请输入字符串1:\n"); scanf("%s",str1); printf("请输入字符串2:\n"); scanf("%s",str2); for(i=0;i<strlen(str1)-strlen(str2)+1;i++) { if(match(str1+i,str2)==strlen(str2)) { result=1; break; } } if(result==1) printf("字符串2是字符串1的子串\n"); else printf("字符串2不是字符串1的子串\n"); return 0; }
我们还可以使用递归函数来判断一个字符串是否包含另一个字符串。在上面的代码中,我们定义了一个match函数,用于判断字符串s1中从当前位置开始的子串是否与字符串s2相等。如果相等,则返回字符串s2的长度;否则返回0。
在主函数中,我们通过循环遍历字符串1中的每个字符,并使用match函数来判断以当前字符为起始的子串是否与字符串2相等。如果找到一个符合要求的子串,则认为字符串2是字符串1的子串。否则,在循环结束时,我们将result变量的值置为0,表示字符串2不是字符串1的子串。
四、使用KMP算法判断
#include<stdio.h> #include<string.h> void getNext(char *p,int *next) { int i=0,j=-1; next[0]=-1; while(i<strlen(p)-1) { if(j==-1||p[i]==p[j]) { i++; j++; next[i]=j; } else j=next[j]; } } int KMP(char *s,char *p) { int next[strlen(p)]; getNext(p,next); int i=0,j=0; while(i<strlen(s)&&j<strlen(p)) { if(j==-1||s[i]==p[j]) { i++; j++; } else j=next[j]; } if(j==strlen(p)) return i-j; else return -1; } int main() { char str1[50],str2[50]; int pos=-1; printf("请输入字符串1:\n"); scanf("%s",str1); printf("请输入字符串2:\n"); scanf("%s",str2); pos=KMP(str1,str2); if(pos!=-1) printf("字符串2是字符串1的子串\n"); else printf("字符串2不是字符串1的子串\n"); return 0; }
KMP算法是一种高效的字符串匹配算法,可以在O(n+m)的时间复杂度内完成字符串匹配。在上面的代码中,我们先通过getNext函数来构建字符串2的next数组,用于辅助KMP算法进行匹配。在getNext函数中,我们使用i和j两个变量来遍历字符串p,并通过next数组来记录当前匹配失败时应该回退的位置。
在KMP函数中,我们使用i和j两个变量来遍历字符串s和p,在匹配失败时,通过next数组快速回退到下一个开始匹配的位置。最后,如果匹配成功,则返回匹配成功的位置;反之则返回-1。
五、总结
本文介绍了四种不同的方法来判断一个字符串是否包含子串。其中,strstr函数是最简单且最好理解的方法;循环遍历和递归函数则比较容易实现,但效率稍低;KMP算法则是最优秀的字符串匹配算法,可以在较短的时间内完成匹配。
无论使用哪种方法,都需要仔细考虑边界情况和特殊情况,以保证计算结果的正确性。在实际编程中,我们还可以根据不同的应用场景来选择最合适的方法,以尽可能提高程序的执行效率。