1. 程式人生 > >劍指offer 面試題35擴充套件:從第一個字串中刪除第二個字串中的所有字元 (C++版)

劍指offer 面試題35擴充套件:從第一個字串中刪除第二個字串中的所有字元 (C++版)

題目描述:

例如,輸入”They are students.””aeiou”,則刪除之後的第一個字串變成”Thy r stdnts.”

思路分析:

總體來說,就是在第一字元中拿到一個字元,判斷其是否在第二個字串中,在的話,就刪除該字元。

考慮如下幾個問題:

1、如何在字串中刪除一個字元

字串的記憶體是連續分配的,當我們刪除其中一個字元時,就需要把後面所有的字元向前移動一個位元組的位置。因此,對於一個長度為n的字串,刪除一個字元的時間複雜度為O(n)。對於本題而言,假設第二個字串的長度為m,有可能要刪除的字元個數是m,因此刪除的時間複雜度為O(m*n),即O(n^2)。

我們換一種思路。採用在原字串基礎上重新構造刪除後的字串的思路。定義兩個指標,一個slow用來構造新的字串,一個fast用來遍歷原字串。初始兩個指標均指向原字串的第一個位置。如果fast指向的字元不是要刪除的字元,就賦值給slow,然後兩個指標一起後移;如果是要刪除的,就跳過該字元,fast繼續遍歷下一個字元,slow不變。這樣,刪除在O(n)時間內就可以搞定。

2、如何在一個字串中查詢一個字元

我們需要判斷第一個字串中的所有字元是否在第二個字串中存在。最容易想到的辦法是,兩層迴圈遍歷,時間複雜度為O(n^2)。

簡單方法:採用雜湊表的思想:字串的總數是有限的。對於8位的char型字元,共有2^8=256個字元。新建一個256的陣列,把所有元素都初始化為0。對於第二個字串中每一個字元,把它的ascii碼對映為該陣列的索引,把陣列的該索引對應的值設為1。這樣,再查詢第一個字串中的字元是否在第二個字串中就很方便了,根據字元的ascii碼,在陣列對應的下標找到其對應的陣列值,為0表示第二個字串中沒有該字元,為1,表示有,只需要O(1)時間。這樣,查詢長度為n的第一個字串中的字元是否在第二個字串中,時間複雜度降為O(n)。

程式碼及測試:

#include <iostream>
#include <assert.h>
using namespace std;

//在一個字串中刪除某些特定字元
char * deleteChars(char *first, char * second) {
	assert( (NULL != first) && (NULL != second) );

	//標記字元是否在字串second中出現過
	const int tableSize = 256;
	bool hashTable[tableSize]; 
	memset(hashTable, 0, sizeof(hashTable));

	while( *second != '\0') {
		if( !hashTable[ *second ] ) {
			hashTable[ *second ] = true;
		}
		second ++;
	}

	//刪除first中所有出現在second中的字元
	char *fast = first;
	char *slow = first;
	while( *fast != '\0') {
		if( !hashTable[*fast]){
			*slow = *fast;
			++ slow;
		}
		++ fast;
	}
	*slow = '\0';

	return first;//注意這裡應該是first而不是slow,slow此時已經指向first最末尾了
}

void test1() { //second中的字元沒有出現在first中的
	cout << "*****test1 second中的字元沒有出現在first中的:*****";
	char text[] = "abcdbbad";
	char *first = text;
	char second[] = "lmni";
	first = deleteChars(first, second);
	cout << first << endl;
}

void test2() { //second中的字元有出現在first中的
	cout << "*****test1 second中的字元有出現在first中的:*****";
	char text[] = "abcdbbad";
	char *first = text;
	char second[] = "adfghb";
	first = deleteChars(first, second);
	cout << first << endl;
}

int main() {

	test1();
	test2();
	return 0;
}