刪除串中相同的元素:一個做法

有一個問題,如何刪除兩個字符串相同的字符,比如

str1 = "abcdeafg"   str2 = "blimklaaaaa"

要得到:

str1 = "cdefg" str2 = "limkl"

下面直接寫程序,這個程序是我寫的,但是思想是別人的,呵呵

爲了方便討論,假設str1 和 str2 都是ascii碼

  1. void delSameChs(char *str1, char *str2)
  2. {
  3.     //ascii碼是0-255,(準確的說是0-127),所以定義一個臨時數組,其下標就是ascii碼
  4.     //其元素是出現在下標i出現在str1,str2的次數
  5.     int temp[256];
  6.     char *pStr1 = str1;
  7.     char *pStr2 = str2;
  8.    
  9.     memset( &temp, 0, sizeof(temp) ); //清0
  10.     while'/0' != *pStr1 )    //遍歷str1,在temp中設爲1
  11.     {
  12.         temp[ *pStr1 ] = 1;  
  13.         pStr1++;
  14.     }
  15.     while'/0' != *pStr2 )   //遍歷str2, 如果已爲1的,在temp中設爲2,爲2的就是兩個字符串的公共元素
  16.     {
  17.         if( 1 == temp[ *pStr2 ] )
  18.             temp[ *pStr2 ] = 2;
  19.         pStr2++;           
  20.     }
  21.    
  22.     forint i = 0; i < 256; i++ )
  23.     {
  24.         if( 2 == temp[i] )
  25.         {
  26.             delCh(str1, i);   //刪除str1中所有的字符i(如果有的話)
  27.             delCh(str2, i);
  28.         }
  29.     }
  30. }


這樣做的原理是用空間換時間,犧牲了256個整數的空間(可以用char temp[256]來代替),三遍並列的循環可以把兩個數組的相同的元素找出來。如果用常規辦法的話,估計要嵌套循環3遍~

如果是unicode嘛,可以設int temp[65536];

如果是多字節編碼,這個...我也沒想過~

下面看這個 void delChar(char *str, char ch);的實現。

因爲要刪掉所有的i,如果是常規做法,每刪一個元素,後面的就要往前面移動,那就用比較多的時間了。

下面換個做法,看這個代碼:
  1. void delChar( char *str, char ch)
  2. {
  3.     char *pCurr = str; //用來處理刪除後的結果
  4.     char *pTemp = str; //用來掃描源字符串str
  5.     while'/0' != *pTemp )
  6.     {
  7.         if( ch != *pTemp )
  8.         {
  9.             *pCurr = *pTemp;
  10.             pCurr++;   
  11.         }
  12.         pTemp++;
  13.     }
  14.     *pCurr = '/0';
  15. }


這個代碼的思想和常規的不同,移動過去的是不想刪掉的,要刪的反而不移動它。這樣僅需要掃描一次就可以了。

這個樣子實現,整個程序最多僅需掃描5次字符串就可以做完任務了。

還可以擴展,如果刪除多個字符串的相同字符,都是這樣處理,而且複雜度都是O(N)

至於還能不能簡化???我現在想不出來,各位請多多指教啊,在下感激不盡,呵呵。


注:這個delChar的程序的想法是參考STL algorithm中的unique的源碼得到的,特此說明。









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章