面试必备——BM字符串查找算法
字符串的一种基本操作是子字符串查找:给定一端长度为N的文本字符串text和一个长度为M(M<N)的模式字符串pattern,在文本字符串中查找和该模式字符串相同的子字符串。在这互联网时代,字符串查找的需求在很多情景都需要,如在文本编辑器或浏览器查找某个单词、在通信内容中截取感兴趣的模式文本等等。
子字符串查找最简单的实现肯定是暴力查找:
可以看到,暴力查找的最坏时间复杂度为O(N*M),实际应用中往往文本字符串很长(成万上亿个字符),而模式字符串很短,这样暴力算法的时间复杂度是无法接受的。
为了改进查找时间,人们发明了很多字符串查找算法,而今天的主角 BM算法 (Bob Boyer和J Strother Moore发明,简称BM算法)就是其中的一种。
不同于暴力查找算法的逐个字符对比,BM算法充分使用 预处理模式字符串 的信息来尽可能跳过更多的字符。在暴力算法中,比较一个字符串都是从首字母开始,逐个比较下去。一旦发现有不同的字符,就需要从头开始进行下一次比较,就需要将字串中的所有字符一一比较。BM算法的核心思路在于,文本字符串从左到右检索,模式字符串从右到左检索,当模式字符串的一个字符pattern[j]和文本字符串的字符text[i+j]不匹配时,那么在模式字符串中查找字符text[i+j]是否存在索引k,使得pattern[k] == text[i+j],k若存在, k应该为满足条件的最右索引 。此时存在三种情景:
通过这种字符的移动方式来代替逐个比较,正是BM算法的高效的关键所在!那么我们怎么知道文本字符串的字符是否存在于模式字符串中?对的,预处理。我们在查找前,先建立一张包含文本字符串的所有字符的字母表, 这张表中记录着字母表中的每个字符在模式字符串中出现的最靠右的索引,如果在字符在模式字符串中不存在,那么值为-1。
有了这张表,我们在查找时就可以高效的移动i。构建这张表很简单:
构建好表,我们只需要按上面分析的情景,出现字符不匹配时,通过表,把i向右平移到具体位置即可。BM完整算法实现如下:
由于不匹配的情况属于大多数,所以一般情况下,BM算法的时间复杂度为O(N/M),是线性级别的!可以说是非常高效了。但它需要额外的空间字母表大小R,所以BM算法是以空间换时间的。
至此,BM字符串查找算法已经分析完了,其实算是一种比较简单的算法,学习起来很快就能搞懂~
面试必备——KMP字符串查找算法
绛旓細BM绠楁硶鐨勬牳蹇冩濊矾鍦ㄤ簬锛鏂囨湰瀛楃涓蹭粠宸﹀埌鍙虫绱紝妯″紡瀛楃涓蹭粠鍙冲埌宸︽绱锛屽綋妯″紡瀛楃涓茬殑涓涓瓧绗attern[j]鍜屾枃鏈瓧绗︿覆鐨勫瓧绗ext[i+j]涓嶅尮閰嶆椂锛岄偅涔堝湪妯″紡瀛楃涓蹭腑鏌ユ壘瀛楃text[i+j]鏄惁瀛樺湪绱㈠紩k锛屼娇寰梡attern[k] == text[i+j]锛宬鑻ュ瓨鍦紝 k搴旇涓烘弧瓒虫潯浠剁殑鏈鍙崇储寮 銆傛鏃跺瓨鍦ㄤ笁绉嶆儏鏅...
绛旓細鏆村姏绠楁硶锛屽皢鐩爣涓插拰妯″紡涓茬殑姣忎釜瀛楃閮借繘琛屼竴涓姣旇緝銆傛ц兘鏈宸紝浣嗘槸浣跨敤鏈骞匡紝鍥犱负瀹炵幇绠鍗曪紝鑰屼笖鍦ㄥ瓧绗︿覆杈冨皬鐨勬儏鍐典笅鑰楄垂鐨勬ц兘涔熷緢灏忋侽(n*m)RK绠楁硶鎶婂瓧绗︿覆姣旇緝闂锛岃浆鎹负浜咹ash鍊兼瘮杈冮棶棰樸 灏嗘ā寮忎覆t鐨勬瘡涓瓧绗︾殑姣旇緝鏀规垚浜嗗皢涓蹭綔涓烘暣浣撲笌鐩爣涓茶繘琛屽搱甯屽兼瘮杈冿紝杩欐牱灏卞噺灏戜簡姣旇緝娆℃暟 ...
绛旓細} return charStep;}/* 绠楁硶鏍稿績鎬濇兂锛屼粠宸﹀悜鍙冲尮閰嶏紝閬囧埌涓嶅尮閰嶇殑鐪嬪ぇ涓涓尮閰嶈寖鍥翠箣澶栫殑鍙充晶绗竴涓瀛楃鍦ㄥ皬涓蹭腑鐨勬渶鍙充綅缃 鏍规嵁浜嬪厛璁$畻濂界殑绉诲姩姝ラ暱绉诲姩澶т覆鎸囬拡锛岀洿鍒板尮閰*/int sundaySearch(char *mainStr,char *subStr,int *charStep){ int mainStrLen=strlen(mainStr); int ...
绛旓細涓鑸楠わ細 锛1锛夌‘瀹氳鍖洪棿鐨勪腑闂翠綅缃甂锛 锛2锛夊皢鏌ユ壘鐨勫糡涓巃rray[k]姣旇緝銆 鑻ョ浉绛夛紝鏌ユ壘鎴愬姛杩斿洖姝や綅缃紱鍚﹀垯纭畾鏂扮殑鏌ユ壘鍖哄煙锛岀户缁簩鍒嗘煡鎵俱傛瘡涓娆℃煡鎵句笌涓棿鍊兼瘮杈冿紝鍙互纭畾鏄惁鏌ユ壘鎴愬姛锛屼笉鎴愬姛褰撳墠鏌ユ壘鍖洪棿灏嗙缉灏忎竴鍗婏紝閫掑綊鏌ユ壘鍗冲彲銆傚師鐞嗭細 涓绉嶉氳繃閲嶅灏嗛棶棰樺垎瑙d负鍚岀被鐨勫瓙闂...
绛旓細鎺掑簭涓庢悳绱細鎺掑簭绠楁硶濡傚啋娉°佸揩閫熷拰褰掑苟锛屾悳绱㈢畻娉曞骞垮害浼樺厛鍜屼簩鍒嗘煡鎵撅紝杩欎簺鏄暟鎹鐞嗙殑鏍稿績鐜妭銆傚瓧绗︿覆澶勭悊锛氫粠BM銆並MP鍒癇F鍜孠MP锛屽瓧绗︿覆鍖归厤绠楁硶鏄枃鏈鐞嗙殑閲嶈宸ュ叿銆傜嚎鎬ц〃鎿嶄綔锛氬浼氬幓閲嶃佹煡鎵炬渶澶у厓绱犲拰浣跨敤鍗曡皟鏍堬紝閾捐〃鐨勫疄鐜版洿鏄笉鍙垨缂虹殑鎶鑳姐傚爢鏍堜笌闃熷垪锛屽浘绠楁硶锛氱悊瑙h繖涓ょ鏁版嵁缁撴瀯锛...
绛旓細绗竴娆$湅鍒拌繖涓悕瀛楃殑鏃跺欒寰楅潪甯搁珮绾э紝娣卞叆瀛︿範灏卞彂鐜帮紝AC灏辨槸涓绉嶅妯″紡瀛楃涓鍖归厤绠楁硶銆傚墠闈粙缁嶇殑BF绠楁硶锛孯K绠楁硶锛BM绠楁硶锛孠MP绠楁硶閮藉睘浜庡崟妯″紡鍖归厤绠楁硶锛岃孴rie鏍戞槸澶氭ā寮忓尮閰嶇畻娉曪紝澶氭ā寮忓尮閰嶇畻娉曞氨鏄湪涓涓富涓蹭腑鏌ユ壘澶氫釜妯″紡涓诧紝涓句釜鏈甯哥敤鐨勪緥瀛愶紝姣斿鎴戜滑鍦ㄨ鍧涘彂琛ㄨ瘎璁烘垨鍙戝笘鐨勬椂鍊欙紝涓鑸鍧...
绛旓細涓涓崟璇嶅墠缂鏍戠殑棰橈紝浣嗘槸鎴戝嵈鐢╰rie鏍+bm绠楁硶绠鍖栫増鍋氱殑 瀵嗙爜鐮磋瘧 銆愰棶棰樻弿杩般戠敱浜庢渶杩戝姛璇捐繃浜庣箒蹇欙紝Tim绔熺劧蹇樿浜嗚嚜宸辩數鑴戠殑瀵嗙爜锛屽垢杩愮殑鏄疶im鍦ㄨ璁$數鑴戝瘑鐮佺殑鏃跺欙紝鐢ㄤ簡涓涓潪甯哥壒娈婄殑鏂规硶璁板綍涓嬩簡瀵嗙爜銆傝繖涓柟娉曟槸锛歍im鎶婂瘑鐮佸拰鍏跺畠鐨勪竴浜涘亣瀵嗙爜鍏卞悓璁板綍鍦ㄤ簡涓涓湰瀛愪笂闈備负浜嗚兘澶熶粠杩欎簺瀛楃涓涓...
绛旓細绗8绔犱粙缁瀛楃涓鍖归厤绠楁硶,鍖呮嫭BF绠楁硶銆丷K绠楁硶銆BM绠楁硶銆並MP绠楁硶銆乀rie鏍戝拰AC鑷姩鏈恒傜9绔犱粙缁嶅浘鍙婄浉鍏崇畻娉,鍖呮嫭娣卞害浼樺厛鎼滅储銆佸箍搴︿紭鍏堟悳绱佹嫇鎵戞帓搴忋丏ijkstra绠楁硶銆丗loyd绠楁硶銆丄*绠楁硶銆乑灏忕敓鎴愭爲绠楁硶銆乑澶ф祦绠楁硶鍜孼澶т簩鍒嗗尮閰嶇瓑銆傜10绔犱粙缁4绉嶇畻娉曟濇兂,鍖呮嫭璐績銆佸垎娌汇佸洖婧拰鍔ㄦ佽鍒掋傜11绔犱粙缁4涓粡鍏...
绛旓細鍦╓ord缂栬緫涓紝妯″紡鍖归厤鏌ユ壘涓兘浣跨敤鐨勯氶厤绗︽槸锛*鍜?銆傛ā寮忓尮閰嶏紝鏁版嵁缁撴瀯涓瀛楃涓鐨勪竴绉嶅熀鏈繍绠楋紝缁欏畾涓涓瓙涓诧紝瑕佹眰鍦ㄦ煇涓瓧绗︿覆涓鎵惧嚭涓庤瀛愪覆鐩稿悓鐨勬墍鏈夊瓙涓诧紝杩欏氨鏄ā寮忓尮閰嶃傚亣璁綪鏄粰瀹氱殑瀛愪覆锛孴鏄緟鏌ユ壘鐨勫瓧绗︿覆锛岃姹備粠T涓壘鍑轰笌P鐩稿悓鐨勬墍鏈夊瓙涓诧紝杩欎釜闂鎴愪负妯″紡鍖归厤闂銆侾绉颁负妯″紡锛孴绉...
绛旓細瀛楃涓(鏂囨娴)锛岃绠楁渶澶у叕绾︽暟锛屽悎骞朵袱涓湁搴忔暟缁勶紝鐚滄暟瀛楁父鎴忥紝璁 绠楀勾榫勭瓑绛夈01绗竴闃舵锛氱啛鎮塒ython 浜斻佹暟鎹粨鏋(6灏忔椂)锛氭爤.闃熷垪锛屽瓧鍏.鍏冪粍锛屾爲锛岄摼琛ㄣ傚浘 鍏侀潰鍚戝璞$紪绋(oop) (6灏忔椂) 锛氬璞★紝绫伙紝鏂规硶鍜屾瀯閫犲嚱鏁帮紝闈㈠悜瀵硅薄 缂栫▼涔嬬户鎵 涓冦绠楁硶(6灏忔椂)鎼滅储(绾挎у拰浜屽垎鏌ユ壘)鎺掑簭(...