5-29 刪除字符串中的子串


輸入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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM