輸入2個字符串S1和S2,要求刪除字符串S1中出現的所有子串S2,即結果字符串中不能包含S2。
輸入格式:
輸入在2行中分別給出不超過80個字符長度的、以回車結束的2個非空字符串,對應S1和S2。
輸出格式:
在一行中輸出刪除字符串S1中出現的所有子串S2后的結果字符串。
輸入樣例:
Tomcat is a male ccatat
cat
輸出樣例:
Tom is a male
解題思路:
1. 基礎算法(算法一)
用了好久才寫出來。最鬧人的情況是諸如 s1 為 paatt,s2 為 at 的情況。因為不單單是刪除子串,刪除子串之后在新的字符串中還要檢查是否有子串。
解題思路:
- 掃描,發現有子串時,刪除子串(將后面的子串向前移),然后置 i = 0,又會開始掃描,掃描出口即是
s1[1] != NULL
; - 處理中要注意如 s1 為 ccat,s2 為 cat 的情況。在掃描第二個 c 的時候,也就是說已經匹配了一部分字符后,之后不再匹配,要將當前的字符再與子串的第一個字符比較,這里第二個也是 c,與子串首字母相同,所以置 count = 1;
- 注意處理要刪除的子串在字符串末尾的情況
puts 函數一直輸出到 NULL(即 '\0')為止,並將 NULL 轉為 '\n' 輸出。所以注意在字符串的最后添加 NULL;
2. 使用字符串處理函數(算法二)
使用 C 程序自帶的字符串處理函數能更加方便地處理問題。代碼也會變得非常簡潔。
注意 strcpy, strcat 中的傳入參數的內存地址不能重疊。否則會出錯。剛開始的時候犯了這個錯,導致有兩個測試點通不過。
算法一
#include<stdio.h>
int main ()
{
char s1[81], s2[81];
gets(s1);
gets(s2);
int i = 0, j = 0, count = 0;
while (s1[i] != NULL) {
if (s2[count]==NULL && count>0) {
j = i - count;
while (s1[i] != NULL) {
s1[j++] = s1[i++];
}
s1[j] = NULL;
i = 0;
count = 0;
continue;
}
if (s1[i] == s2[count]) {
count ++;
} else if (s1[i] == s2[0]) {
count = 1; // 每一次不再匹配后,都要再和子串的第一個字符比較,以免漏過如s1為ccat (s2為 cat)的情況
} else {
count = 0;
}
i++;
}
if (s2[count]==NULL && count>0) {
s1[i-count] = NULL;
} //處理要刪除的字串在 s1 末尾的情況
puts(s1); //puts 函數遇 NULL 才會結束
return 0;
}
算法二
#include<stdio.h>
#include<string.h>
int main(void)
{
char a[81];
gets(a);
char b[81];
gets(b);
char *p;
char c[81];
while((p=strstr(a,b)) != NULL) { //strstr 找不到返回 NULL
*p = '\0'; // 指定連接下一步(連接函數)之前 a 的終止位置;
strcpy (c, p+strlen(b)); // strcat 函數中的兩個傳入參數的內存地址不能重疊,所以這里用 c 當作 temp
strcat (a, c);
}
puts(a);
return 0;
}