字串匹配演算法問題小記

2021-09-26 22:38:30 字數 3985 閱讀 3029

bf演算法也叫樸素模式匹配演算法,是由bruce force提出來的,演算法基本思想就是簡單粗暴的一次比較的問題。演算法的c**實現很簡單,但是在操作中遇到了一些細節問題。

問題**

#include

#include

#include

#define len 100

intb_findex

(char s,

char t)

// end if

else

// end else

}//end while

if(j >=len_t)

else

}//end bf

intmain

(int argc,

char

* ar**)

這段**初看沒什麼問題,與其他部落格的**沒什麼差別,編譯也能順利通過,但是卻無法100%正確匹配,為什麼這麼說?

case1:子串=主串

hello world

hello world

success patterened at 0

process returned 0

(0x0

) execution time :

16.536 s

press any key to continue

.

能正確輸出期望值。

case2:子串《主串

hello world

hello

fail patterened

process returned 0

(0x0

) execution time :

9.249 s

press any key to continue

.

這是什麼原因造成的?

由於scanf()函式只能接收連續的字串,遇到空格便結束,對匹配的功能有所影響,所以選擇了fgets()函式(比gets()函式更安全、通用)。

如果我們直接換用gets()函式在一般的應用中是沒有問題的,上述**可以正常工作。但是gets()函式的最大問題在於它不檢查輸入是否超過了陣列長度,這將引起記憶體溢位的安全問題。

真正造成問題的原因在與fgets()與gets()的另乙個差別上:

fgets()也是逐個讀入字元,直到遇到首個換行符或已經讀入了sizeof(str)-1個字元時結束操作。如果讀入了換行符,那麼它會把換行符和其他字元一起儲存

所以關鍵就是換行符的問題。

在case1的情況下,主串字元為he

llow

orld

『\n』

『\0』

字串也為he

llow

orld

『\n』

『\0』

所以匹配成功沒問題。

但是在case2下,字串為he

llo『\n』

『\0』

所以就造成了去匹配時子串是帶上換行符一起去進行匹配。

以上就是問題分析了,解決方法就是在bf函式中求字串長度時吧這個換行符減掉,修改的關鍵**如下

int len_s =

strlen

(s)-1;

// 使用strlen函式獲取字串長度,不包含結束符,

int len_t =

strlen

(t)-1;

// 減1就去掉了換行符。

當然還有其他方法,這裡僅針對該問題提出了針對性修正。

關於演算法的介紹這裡就不列舉了,直接給出c++**

next函式

這裡給出兩種next函式的方法,都能正常工作

/* 求模式全的netx函式

next下標從0開始,初始值定位-1

s:cdbcbabcdbcdbcacabc

t:bcdbcdbca

*/#include

#include

using

namespace std;

intget_next1

(string t,

int next)

if(t[k +1]

== t[i]

|| k ==-1

)///如果字元一樣,繼續向前匹配

next[i]

= k;

///將最大匹配的值賦給next陣列}}

intget_next2

(string t,

int next)

else

j = next[j];}

}int

main

(int argc,

char

* ar**)

;get_next1

(t,next)

; cout <<

"the next of substring t:"

;for

(int i =

0; i size()

; i++

) cout << next[i]

<<

" ";

cout << endl;

get_next2

(t,next)

; cout <<

"the next of substring t:"

;for

(int i =

0; i size()

; i++

) cout << next[i]

<<

" ";

cout << endl;

}

輸出

please input substring: bcdbcdbca

the get_next1 of substring t:-1

0001

2340

the get_next2 of substring t:-1

0001

2345

process returned 0

(0x0

) execution time :

4.611 s

press any key to continue

.

kmp實現

#include

#include

using

namespace std;

/* 得到next陣列

*/void

get_next

(string t,

int*next)

else}}

/* kmp演算法

*/int

kmp(string s, string t,

int*next)

else}if

(j == len_t)

else

}int

main()

輸出

cdbcbabcdbcdbcacabc

bcdbcdbca

模式串的next的值為:-1

0001

2345

success patterned with shift 6

process returned 0

(0x0

) execution time :

19.706 s

press any key to continue

.

正則匹配字串小記

需求1.現有 裝置名 dev.json 裝置名 廠商名 型號名 dev.json 裝置名.json 廠商名 型號名.json 型號名 廠商名.json 裝置名 廠商名 bu.json 等字串,要求匹配出符合規則的字串,並且根據傳入的裝置名或者廠商名或者型號名講字串中對應的內容修改。裝置名 字串規則 ...

字串匹配問題 KMP匹配演算法

基本思想 字串匹配問題 在文字串中尋找是否有與模式串相同的子串 在字串匹配時,暴力匹配忽略了如果模式串開頭與中間有重複部分,在將模式串的後面的重複部分匹配後,無法繼續匹配的話,此時將模式串開頭實際上也已經被匹配了,可以直接從開頭重複部分之後開始匹配 這裡引入了乙個部分匹配值表,每個與模式串的字元對應...

字串匹配演算法 字串匹配演算法總覽

字串匹配在文字處理裡非常重要,我們採用簡潔的python 把以下演算法一一實現並講解。樸素演算法 algorithm rabin karp 演算法 有限自動機演算法 finite automation knuth morris pratt 演算法 kmp algorithm boyer moore ...