KMP算法C++代码
2008-08-20 19:36
204 查看
//by baihacker
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
using namespace std;
template<typename FType, typename SType>
struct equal_cmp
{
bool operator ()(const FType& _F, const SType& _S)const
{return _F == _S;}
};
template<typename RandAccessConcept,
typename EqualCmp>
inline void
CalFailFunction(
const RandAccessConcept& in,
int len,
vector<int>& ff,
EqualCmp cmp
)
{
ff.clear();
ff.reserve(len);
ff.push_back(-1);
for (int curr = 1, k = -1; curr < len; ++curr)
{
for (;k >= 0 && !cmp(in[k+1], in[curr]);
k = ff[k]);
if (cmp(in[k+1], in[curr])) ++k;
ff.push_back(k);
}
}
template<typename FRandAccessConcept,
typename SRandAccessConcept,
typename EqualCmp>
inline int
KMPSearchFirst(
const FRandAccessConcept& d,
int dlength,
const SRandAccessConcept& p,
int plength,
EqualCmp cmp,
int start = 0
)
{
vector<int> ff;
CalFailFunction(p, plength, ff, cmp);
for (int i = start, j = -1; i < dlength; ++i)
{
while (j >= 0 && !cmp(d[i], p[j+1])) j = ff[j];
if (cmp(d[i], p[j+1])) ++j;
if (j == plength - 1) return i - plength + 1;
}
return -1;
}
template<typename FRandAccessConcept,
typename SRandAccessConcept,
typename EqualCmp>
inline int
KMPSearchALL(
const FRandAccessConcept& d,
int dlength,
const SRandAccessConcept& p,
int plength,
vector<int>& result,
EqualCmp cmp
)
{
vector<int> ff;
CalFailFunction(p, plength, ff, cmp);
result.clear();
for (int i = 0, j = -1; i < dlength; ++i)
{
while (j >= 0 && !cmp(d[i], p[j+1])) j = ff[j];
if (cmp(d[i], p[j+1])) ++j;
if (j == plength - 1)
{
result.push_back(i - plength + 1);
j = ff[j];
}
}
return result.size();
}
int main()
{
int d[] = {1,2,3,1,2,3,1,2};
char p[] = "/1/2/3/1/2";
vector<int> result;
int found = KMPSearchALL(d, 8, p, 5, result, equal_cmp<int, char>());
for (int i = 0; i < found; ++i)
cout << result[i] << " ";
cout << endl;
return 0;
}
2013/06/29 : 更新一些能直接使用并用于较短模式串的代码。推荐一本叫《柔性字符串匹配》的书
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
using namespace std;
template<typename FType, typename SType>
struct equal_cmp
{
bool operator ()(const FType& _F, const SType& _S)const
{return _F == _S;}
};
template<typename RandAccessConcept,
typename EqualCmp>
inline void
CalFailFunction(
const RandAccessConcept& in,
int len,
vector<int>& ff,
EqualCmp cmp
)
{
ff.clear();
ff.reserve(len);
ff.push_back(-1);
for (int curr = 1, k = -1; curr < len; ++curr)
{
for (;k >= 0 && !cmp(in[k+1], in[curr]);
k = ff[k]);
if (cmp(in[k+1], in[curr])) ++k;
ff.push_back(k);
}
}
template<typename FRandAccessConcept,
typename SRandAccessConcept,
typename EqualCmp>
inline int
KMPSearchFirst(
const FRandAccessConcept& d,
int dlength,
const SRandAccessConcept& p,
int plength,
EqualCmp cmp,
int start = 0
)
{
vector<int> ff;
CalFailFunction(p, plength, ff, cmp);
for (int i = start, j = -1; i < dlength; ++i)
{
while (j >= 0 && !cmp(d[i], p[j+1])) j = ff[j];
if (cmp(d[i], p[j+1])) ++j;
if (j == plength - 1) return i - plength + 1;
}
return -1;
}
template<typename FRandAccessConcept,
typename SRandAccessConcept,
typename EqualCmp>
inline int
KMPSearchALL(
const FRandAccessConcept& d,
int dlength,
const SRandAccessConcept& p,
int plength,
vector<int>& result,
EqualCmp cmp
)
{
vector<int> ff;
CalFailFunction(p, plength, ff, cmp);
result.clear();
for (int i = 0, j = -1; i < dlength; ++i)
{
while (j >= 0 && !cmp(d[i], p[j+1])) j = ff[j];
if (cmp(d[i], p[j+1])) ++j;
if (j == plength - 1)
{
result.push_back(i - plength + 1);
j = ff[j];
}
}
return result.size();
}
int main()
{
int d[] = {1,2,3,1,2,3,1,2};
char p[] = "/1/2/3/1/2";
vector<int> result;
int found = KMPSearchALL(d, 8, p, 5, result, equal_cmp<int, char>());
for (int i = 0; i < found; ++i)
cout << result[i] << " ";
cout << endl;
return 0;
}
2013/06/29 : 更新一些能直接使用并用于较短模式串的代码。推荐一本叫《柔性字符串匹配》的书
template<typename ElemType> int MatchSO(ElemType* t, int n, ElemType* p, int m, vector<int>& result) { typedef unsigned long long NumberType; const int CharSet = 128; NumberType B[CharSet]; NumberType D = ~0; NumberType Check = 1 << (m-1); NumberType BIT = 1; for (int i = 0; i < CharSet; ++i) B[i] = ~0; for (int i = 0; i < m; ++i, BIT <<= 1) B[p[i]] &= ~BIT; result.clear(); for (int i = 0; i < n; ++i) { D = (D << 1) | B[t[i]]; if ((D & Check) == 0) result.push_back(i-m+1); } return result.size(); } template<typename ElemType> int MatchSA(ElemType* t, int n, ElemType* p, int m, vector<int>& result) { typedef unsigned long long NumberType; const int CharSet = 128; NumberType B[CharSet]; NumberType D = 0; NumberType Check = 1 << (m-1); NumberType BIT = 1; for (int i = 0; i < CharSet; ++i) B[i] = 0; for (int i = 0; i < m; ++i, BIT <<= 1) B[p[i]] |= BIT; result.clear(); for (int i = 0; i < n; ++i) { D = ((D << 1) | 1) & B[t[i]]; if ((D & Check) != 0) result.push_back(i-m+1); } return result.size(); } template<typename ElemType> int MatchKMP(ElemType* t, int n, ElemType* p, int m, vector<int>& result) { int * Prefix = new int[m]; { Prefix[0] = -1; for (int i = 1, F = -1; i < m; ++i) { while (F >= 0 && p[F+1] != p[i]) F = Prefix[F]; if (p[F+1] == p[i]) ++F; Prefix[i] = F; } } { result.clear(); for (int i = 0, F = -1; i < n; ++i) { while (F >= 0 && p[F+1] != t[i]) F = Prefix[F]; if (p[F+1] == t[i]) ++F; if (F+1 == m) { result.push_back(i-m+1); F = Prefix[F]; } } } delete[] Prefix; return result.size(); }
相关文章推荐
- KMP算法C++代码
- kmp算法c++代码实现
- KMP算法的C++实现代码
- 字符串匹配KMP算法C++代码实现
- 经典KMP算法C++与Java实现代码
- KMP算法C++代码
- 卡尔曼滤波简介及其算法实现代码(C++/C/MATLAB)
- 传统高斯模糊与优化算法(附完整C++代码)
- 使用C/C++实现Socket聊天程序(代码+实验报告)
- c++怎么计算代码运行时间到超精确毫秒级别
- C++错误之严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C4996 'strcpy':
- C++变量生命周期探索代码
- c++面试题:在不改变任何代码的情况下 输出hello world!
- 在Qt中使用C++代码创建界面
- Matlab代码转C++(一)
- 用C++/CLI编写ASP.Net的后台代码
- C++之内存存储+一条进程的栈区、堆区、数据区和代码区在内存中的映射
- C++学习之旅——函数重载代码,必须得看看怎么写的
- 在C/C++代码中使用SSE等指令集的指令(5)SSE进行加法运算简单的性能测试
- 一小段C++代码分析,看看你能写出输出结果吗,很简单的!