Boyer-Moore 精確匹配演算法實現(C/C++)
演算法原理這裡不廢話,網上找到的演算法很多再臨界情況的處理都有錯誤,所以自己重寫了一個。
預處理建立shift資源表時的效率比較一般,但是簡單易懂! 如果你有更好的版本希望發來研究研究。
/*
* Boyer-Moore 精確匹配演算法
* -------------------------------------------
* copyright (c) 2012 Niu Chenguang <chrisniu1984@gmail.com>
*
* file: bm.h
*/
#ifndef __BM_H__
#define __BM_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BM_SKIP_SIZE 256
#define BM_SHIFT_SIZE 128 // 此值決定字串最大長度
/*
* 為已知字串建立skip資源表。
*
* @skip: [in/out] 儲存skip資源的int陣列。元素數必須為BM_SIKP_SIZE個。
* @sub: [in] 已知字串
* @sub_len: [in] 字串長度
*
* @RETURN: 0 = 成功,-1 = 失敗
*/
static inline int bm_make_skip(int skip[], unsigned char *sub, int sub_len)
{
if (NULL == skip || NULL == sub || sub_len <= 0) {
return -1;
}
memset(skip, 0x00, sizeof(int)*BM_SKIP_SIZE);
int i;
for (i=0; i<BM_SKIP_SIZE; i++) {
skip[i] = sub_len;
}
while (sub_len != 0) {
skip[*sub] = --sub_len;
sub++;
}
return 0;
}
/*
* 為已知字串建立shift資源表。
*
* @shift: [in/out] 儲存shift資源的int陣列。元素數必須為BM_SHIFT_SIZE個。
* @sub: [in] 已知字串
* @sub_len: [in] 字串長度
*
* @RETURN: 0 = 成功,-1 = 失敗
*/
static inline int bm_make_shift(int shift[], unsigned char* sub,int sub_len)
{
if (NULL == shift || NULL == sub ||
sub_len <= 0 || sub_len > BM_SHIFT_SIZE) {
return -1;
}
memset(shift, 0x00, sizeof(int)*BM_SHIFT_SIZE);
int pos;
for (pos = sub_len-1; pos >= 0; pos--) {
//int i=0;
//printf("---------------------\n");
//printf("%s\n", sub);
//for (i=0; i<pos; i++) {
// printf(" ");
//}
//printf("%s\n", sub+pos);
unsigned char *good = sub + pos + 1; // 好字尾起始位置。
int good_len = sub_len - pos - 1; // 好字尾長度
// 此迴圈是為了匹配到儘量長的好字尾串
while (good_len > 0) {
// p 為開始位置查詢好字尾
unsigned char *p = sub + sub_len - 1 - good_len;
// 此迴圈是為了從右向左逐個位置查詢好字尾串。
while (p >= sub) {
// 在p位置找到了good
if (memcmp(p, good, good_len) == 0) {
shift[pos] = (sub_len-pos)+(good-p)-1;
break;
}
// 向左移動一個位置,準備繼續查詢good串
p--;
}
// 此shift位置有值,說明查詢成功,直接break
if (shift[pos] != 0) {
break;
}
// 取好字尾的子串
good++;
good_len--;
}
// 此shift位置沒有值,說明沒有匹配到good串及其字串
if (shift[pos] == 0) {
shift[pos] = sub_len-pos;
}
//for(i=0;i<shift[pos]-(sub_len-pos);i++){
// printf(" ");
//}
//printf("%s\n", sub);
}
return 0;
}
static inline int bm_search(unsigned char *str, int str_len,
unsigned char *sub, int sub_len,
int skip[], int shift[])
{
if (sub_len == 0) {
return 1; // 根據實際需要,修改這個返回值。
}
if (sub_len > str_len) {
return 0;
}
int str_end = sub_len - 1;
while (str_end <= str_len) {
int sub_end = sub_len-1;
while (str[str_end] == sub[sub_end]) {
if (sub_end == 0) {
return 1;
}
str_end--;
sub_end--;
}
int skip_stride = skip[str[str_end]];
int shift_stride = shift[sub_end];
str_end += MAX(skip_stride,shift_stride);
}
return 0;
}
#endif // __BM_H__
相關文章
- 圖解BM(Boyer-Moore)字串匹配演算法+程式碼實現圖解字串匹配演算法
- 字串匹配的Boyer-Moore演算法字串匹配演算法
- 模式匹配kmp演算法(c++)模式KMP演算法C++
- C++實現Prim演算法C++演算法
- 快速排序演算法C++實現排序演算法C++
- PHP 身份證精確匹配驗證PHP
- MD5演算法--C++實現演算法C++
- 遺傳演算法與C++實現演算法C++
- 高效字串匹配演算法——BM 演算法詳解(C++)字串匹配演算法C++
- 如何快速又正確地在C++裡實現鎖C++
- c++實現的模擬退火演算法C++演算法
- C++實現蠻力最近對演算法C++演算法
- 利用 C++ 實現 md5 演算法C++演算法
- 各類排序演算法的c++實現排序演算法C++
- NDT演算法詳解與C++實現演算法C++
- 字串查詢演算法總結(暴力匹配、KMP 演算法、Boyer-Moore 演算法和 Sunday 演算法)字串演算法KMP
- [C++]實現memcpyC++memcpy
- C++ binder 實現C++
- 精確統計程式碼量(Java實現)Java
- 設計模式——原型模式(C++)——演算法實現設計模式原型C++演算法
- DES演算法C++程式碼實現-密碼學演算法C++密碼學
- 命令模式(c++實現)模式C++
- 堆排序(實現c++)排序C++
- 堆排序c++實現排序C++
- 常見快取演算法和LRU的c++實現快取演算法C++
- 使用OpenCV和C++實現的分水嶺演算法(Watershed)OpenCVC++演算法
- C/C++—— C++編譯器是如何實現多型C++編譯多型
- 樸素模式匹配演算法java實現模式演算法Java
- Callback在C\C++中的實現C++
- 享元模式(c++實現)模式C++
- 中介者模式(c++實現)模式C++
- 橋接模式(c++實現)橋接模式C++
- 模板方法模式(c++實現)模式C++
- 狀態模式(c++實現)模式C++
- 字典樹及其C++實現C++
- 折半查詢(C++實現)C++
- C++程式設計實現C++程式設計
- LinkBlockedQueue的c++實現BloCC++