【劍指offer】刪除在另一個字串中出現的字元

蘭亭風雨發表於2014-05-27

轉載請註明出處:http://blog.csdn.net/ns_code/article/details/27110873


    劍指offer上的字串相關題目。 

    題目:輸入兩個字串,從第一字串中刪除第二個字串中所有的字元。例如,輸入”They are students.””aeiou”,則刪除之後的第一個字串變成”Thy r stdnts.”

    這裡主要要分析兩個方面:

    1、如何判斷那些字元是需要刪除的字元。同很多字串問題一樣,可以開闢一個雜湊陣列,全部初始化為false,將第二個字串中字元對應的對映位置置為ture,表示這些位置對應的字元在第一個字串中需要刪除。

    2、關於刪除字元的操作,每次刪除一個,而後把後面的元素均左移一位,由於要刪除的字元可能有多個,這種方法的時間複雜度為O(n*n)。我們這裡有O(n)的刪除方法,我們可以設想,當一個字元需要被刪除的時候,我們把它所佔的位置讓它後面的字元來填補,也就相當於這個字元被刪除了。在具體實現中,我們可以定義兩個指標(pFastpSlow),初始的時候都指向第一字元的起始位置。當pFast指向的字元是需要刪除的字元,則pFast直接跳過,指向下一個字元。如果pFast指向的字元是不需要刪除的字元,那麼把pFast指向的字元賦值給pSlow指向的字元,並且pFastpStart同時向後移動指向下一個字元。這樣,前面被pFast跳過的字元相當於被刪除了。用這種方法,整個刪除在O(n)時間內就可以完成。

    前面也有篇刪除重複字元的博文用到了該刪除方法,見這裡:http://blog.csdn.net/ns_code/article/details/21328151

    另外,有一點需要注意,char的範圍在-128-127,unsigned char的範圍才是在0-255,因此ASCII值在128-255之間的字元,如果儲存為了char型,其轉化為int值的範圍是在-128--1之間,這點在下面的程式碼中有體現。

    根據以上思路寫出的程式碼如下:

#include<stdio.h>
#include<string.h>
#define MAX 256

void DeleteChars(char *str1,char *str2)
{
	if(str1==NULL || str2==NULL)
		return;

	bool hashtable[MAX];
	memset(hashtable,0,sizeof(hashtable));

	//將str2中字元對應的hashtable陣列中的位置上的值設為ture
	while(*str2 != '\0')
	{
		//ASCII值在128-255之間的的字元,
		//用char儲存,轉化為int型,在-128--1之間
		int index;
		if(*str2 >= 0)
			index = *str2;
		else
			index = *str2 + 256;

		hashtable[index] = true;
		++str2;
	}

	char *pFast = str1;
	char *pSlow = str1;
	while(*pFast != '\0')
	{
		int index;
		if(*pFast >= 0)
			index = *pFast;
		else
			index = *pFast + 256;

		//無論是否碰到要刪除的字元,pFast都後移,
		//只有沒碰到要刪除的字元時,pSlow才後移
		if(!hashtable[index])
			*pSlow++ = *pFast;	
		++pFast;
	}
	*pSlow = '\0';
}

int main()
{

	char str1[] = "They are students";
	char str2[] = "Tt";
	DeleteChars(str1,str2);
	puts(str1);
	return 0;
}
    測試結果:



相關文章