編譯環境
本系列文章所提供的算法均在以下環境下編譯通過。
【算法編譯環境】Federa 8,linux 2.6.35.6-45.fc14.i686
【處理器】 Intel(R) Core(TM)2 Quad CPU Q9400 @ 2.66GHz
【內存】 2025272 kB
前言
本篇文章和上一篇文章所采用思路同出一則,做為兩篇來講,是覺得如果文章太長需要翻頁很多,顯然不好。顯然長篇大論會讓人不僅僅視覺疲勞,也會讓人很不耐煩。除非幽默風趣生動。才能讓小伙伴們有耐心看下去。好了, 閑話不多說。書接上回,上文用到的方法大致可以總結為:“一次掃描,向左平移”。時間復雜度為O(N)。本次算法依然采用這種方法。當然本題還用到了 “字符串hash”,這種方法也在不少算法中取得了四兩撥千斤的效果,小伙伴們要記住這些名詞。這讓我突然想到了小時候做數學題時的小技巧。這些大概就是屬於小技巧,我們可以稱之為“算法小技巧”。
本系列文章均系筆者所寫,難免有一些錯誤或者紕漏,如果小伙伴們有好的建議或者更好的算法,請不吝賜教。
正文
【題目】
輸入兩個字符串,從第一字符串中刪除第二個字符串中所有的字符。
【例子】
輸入”They are students.” 和”aeiou”則刪除之后第一個字符串變成 Thy r stdnts。
【分析】
這道題來之微軟,也不是很難。這說明牛X的公司也未必全是難題。所以小伙伴們不要被公司給嚇倒。
就本題來講,大致思路在上面也提到,就是對字符串1進行掃描,然后判斷當前字符是否在子字符串中出現,如果出現,則忽略不計,繼續下一位,反之則復制到i指針處(i指針是指向輸出的位置,初始化為0)。
那這里有一個問題了,判斷一個字符在字符串2中是否出現,如果用平時的方法,需要O(N)復雜度。顯然不行。那什么方法是O(1)呢?當然只有hash算法了。“字符串hash”,我們可以把這個當作專有名詞記住,讓你在任何時候都知道用它。,我們對字符串2進行hash初始化,然后對字符串1就可以直接判斷了。這里舉一個例子吧。(雖然很簡單,但也有可能我表達不清晰,讓大家有所誤解。)ASCII編碼至於256個,每個char類型其實都是一個整數,在C語言里面我們可以定義int hash_table[256]。比如A的值是65,如果A存在則我們只要設置hash_table[(int)'A'] = 1即可。
上面一堆廢話,其實大致可以總結如下:
用i指針來控制輸出,j指針來處理子字符串出現的字符。這么說簡單明了吧。
算法的文字描述如下:
第一步:初始化hash表,並將子字符串中出現的字符對應的hash表位置設置1;
第二步:用i指針控制輸出開始為0,j指針從0處開始掃描;
第三步:當j遇見第一個子字符串中未的字符,賦給i處.i指向下一位;反之,跳過;
第四步:循環第三步,直到字符串末尾停止。。
【代碼】
#include <iostream> #include <cstring> char * string_del_characters( char * const src, const char * const dest ) { int destLen = strlen( dest ); int hash_table[256] = { 0 }; char * p = src; int index = 0; for( int i = 0; i < destLen; i++ ) { hash_table[ (int)dest[i] ] = 1; } while( *p != '\0' ) { if( 0 == hash_table[(int)*p] ) { src[index++] = *p; } p++; } src[index] = '\0'; return src; } int main( int argc, char ** argv ) { char src[] = "They are students."; char dest[] = "aeiou"; char * pResult = string_del_characters( src, dest ); std::cout << pResult << std::endl; }
【結論】
作者
出處:http://www.cnblogs.com/gina
本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
