str1 = "abcdeafg" str2 = "blimklaaaaa"
要得到:
str1 = "cdefg" str2 = "limkl"
下面直接寫程序,這個程序是我寫的,但是思想是別人的,呵呵
爲了方便討論,假設str1 和 str2 都是ascii碼
- void delSameChs(char *str1, char *str2)
- {
- //ascii碼是0-255,(準確的說是0-127),所以定義一個臨時數組,其下標就是ascii碼
- //其元素是出現在下標i出現在str1,str2的次數
- int temp[256];
- char *pStr1 = str1;
- char *pStr2 = str2;
- memset( &temp, 0, sizeof(temp) ); //清0
- while( '/0' != *pStr1 ) //遍歷str1,在temp中設爲1
- {
- temp[ *pStr1 ] = 1;
- pStr1++;
- }
- while( '/0' != *pStr2 ) //遍歷str2, 如果已爲1的,在temp中設爲2,爲2的就是兩個字符串的公共元素
- {
- if( 1 == temp[ *pStr2 ] )
- temp[ *pStr2 ] = 2;
- pStr2++;
- }
- for( int i = 0; i < 256; i++ )
- {
- if( 2 == temp[i] )
- {
- delCh(str1, i); //刪除str1中所有的字符i(如果有的話)
- delCh(str2, i);
- }
- }
- }
這樣做的原理是用空間換時間,犧牲了256個整數的空間(可以用char temp[256]來代替),三遍並列的循環可以把兩個數組的相同的元素找出來。如果用常規辦法的話,估計要嵌套循環3遍~
如果是unicode嘛,可以設int temp[65536];
如果是多字節編碼,這個...我也沒想過~
下面看這個 void delChar(char *str, char ch);的實現。
因爲要刪掉所有的i,如果是常規做法,每刪一個元素,後面的就要往前面移動,那就用比較多的時間了。
下面換個做法,看這個代碼:
- void delChar( char *str, char ch)
- {
- char *pCurr = str; //用來處理刪除後的結果
- char *pTemp = str; //用來掃描源字符串str
- while( '/0' != *pTemp )
- {
- if( ch != *pTemp )
- {
- *pCurr = *pTemp;
- pCurr++;
- }
- pTemp++;
- }
- *pCurr = '/0';
- }
這個代碼的思想和常規的不同,移動過去的是不想刪掉的,要刪的反而不移動它。這樣僅需要掃描一次就可以了。
這個樣子實現,整個程序最多僅需掃描5次字符串就可以做完任務了。
還可以擴展,如果刪除多個字符串的相同字符,都是這樣處理,而且複雜度都是O(N)
至於還能不能簡化???我現在想不出來,各位請多多指教啊,在下感激不盡,呵呵。
注:這個delChar的程序的想法是參考STL algorithm中的unique的源碼得到的,特此說明。