一、使用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演算法則是最優秀的字元串匹配演算法,可以在較短的時間內完成匹配。
無論使用哪種方法,都需要仔細考慮邊界情況和特殊情況,以保證計算結果的正確性。在實際編程中,我們還可以根據不同的應用場景來選擇最合適的方法,以儘可能提高程序的執行效率。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/245503.html