用c++后缀自动机实现最大公共字符串算法,并封装成Python库
后缀自动机的C++代码转自https://e-maxx.ru/algo/suffix_automata,其余封装为自写。
在C++文件同级目录建立setup.py文件,代码如下:
# !/usr/bin/env python
from distutils.core import setup, Extension
mod = "sam"
setup(name=mod, ext_modules=[Extension(mod, sources=['sam_lcs.cpp'])])
封装完后缀自动机的源码后,命令行编译、安装、卸载,安装后即可在Python里import调用:
python setup.py build
python setup.py install
python setup.py uninstall
包装模块的C++函数编写如下:
#include <map>
#include <string>
#include <Python.h> using namespace std; struct state
{
int len, link;
map<char, int> next;
}; const int MAXLEN = ;
state st[MAXLEN * ];
int sz, last; void sa_init()
{
sz = last = ;
st[].len = ;
st[].link = -;
++sz;
// 清除状态:
for (int i = ; i < MAXLEN * ; ++i)
st[i].next.clear();
}; void sa_extend(char c)
{
int cur = sz++;
st[cur].len = st[last].len + ;
int p;
for (p = last; p != - && !st[p].next.count(c); p = st[p].link)
st[p].next[c] = cur;
if (p == -)
st[cur].link = ;
else
{
int q = st[p].next[c];
if (st[p].len + == st[q].len)
st[cur].link = q;
else
{
int clone = sz++;
st[clone].len = st[p].len + ;
st[clone].next = st[q].next;
st[clone].link = st[q].link;
for (; p != - && st[p].next[c] == q; p = st[p].link)
st[p].next[c] = clone;
st[q].link = st[cur].link = clone;
}
}
last = cur;
}; string lcs(string s, string t)
{
sa_init();
for (int i = ; i < (int)s.length(); ++i)
sa_extend(s[i]); int v = , l = ,
best = , bestpos = ;
for (int i = ; i < (int)t.length(); ++i)
{
while (v && !st[v].next.count(t[i]))
{
v = st[v].link;
l = st[v].len;
}
if (st[v].next.count(t[i]))
{
v = st[v].next[t[i]];
++l;
}
if (l > best)
best = l, bestpos = i;
}
return t.substr(bestpos - best + , best);
}; static PyObject *sam_lcs(PyObject *self, PyObject *args)
{
char *stmp, *ttmp;
string s, t;
if (!PyArg_ParseTuple(args, "ss", &stmp, &ttmp))
return NULL;
s = stmp;
t = ttmp;
return PyUnicode_FromString(lcs(s, t).c_str());
}; static PyMethodDef sam_lcs_Methods[] = {
{"lcs", sam_lcs, METH_VARARGS,
"Get a longest common string of two strings with SAM"},
{NULL, NULL, , NULL}}; static struct PyModuleDef sam = {
PyModuleDef_HEAD_INIT,
"sam",
"SAM",
-,
sam_lcs_Methods}; PyMODINIT_FUNC
PyInit_sam(void)
{
return PyModule_Create(&sam);
};
编译安装完成后,就可以在Python里调用了
用c++后缀自动机实现最大公共字符串算法,并封装成Python库的更多相关文章
- 后缀自动机----一种将字符串变成DAG的方法
后缀自动机 (suffix automaton, SAM) 是一个能解决许多字符串相关问题的有力的数据结构.(否则我们也不会用它) 举几个例子,以下的字符串问题都可以在线性时间内通过 SAM 解决 1 ...
- SPOJ LCS 后缀自动机找最大公共子串
这里用第一个字符串构建完成后缀自动机以后 不断用第二个字符串从左往右沿着后缀自动机往前走,如能找到,那么当前匹配配数加1 如果找不到,那么就不断沿着后缀树不断往前找到所能匹配到当前字符的最大长度,然后 ...
- [SPOJ1811]Longest Common Substring 后缀自动机 最长公共子串
题目链接:http://www.spoj.com/problems/LCS/ 题意如题目,求两个串的最大公共子串LCS. 首先对其中一个字符串A建立SAM,然后用另一个字符串B在上面跑. 用一个变量L ...
- 一文读懂后缀自动机 Suffix_Automata
原论文(俄文)地址:suffix_automata 原翻译(中文)地址:后缀自动机详解(DZYO的博客) Upd:强推浅显易懂(?)的SAM讲解 后缀自动机 后缀自动机(单词的有向无环图)--是一种强 ...
- 牛客多校第四场 I string 后缀自动机/回文自动机
这个回文自动机的板有问题,它虽然能过这道题,但是在计算size的时候会出锅! 题意: 求一个字符串中本质不同的连续子串有几个,但是某串和它反转后的字符串算一个. 题解: 要注意的是,一般字符串题中的“ ...
- SPOJ 1811. Longest Common Substring (LCS,两个字符串的最长公共子串, 后缀自动机SAM)
1811. Longest Common Substring Problem code: LCS A string is finite sequence of characters over a no ...
- SPOJ 1811 Longest Common Substring (后缀自动机第一题,求两个串的最长公共子串)
题目大意: 给出两个长度小于等于25W的字符串,求它们的最长公共子串. 题目链接:http://www.spoj.com/problems/LCS/ 算法讨论: 二分+哈希, 后缀数组, 后缀自动机. ...
- BZOJ4032[HEOI2015]最短不公共子串——序列自动机+后缀自动机+DP+贪心
题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ...
- 字符串数据结构模板/题单(后缀数组,后缀自动机,LCP,后缀平衡树,回文自动机)
模板 后缀数组 #include<bits/stdc++.h> #define R register int using namespace std; const int N=1e6+9; ...
随机推荐
- MySQL OCP
http://www.royalwzy.com/ http://www.aixchina.net/home/space.php?uid=898169
- SVN环境搭建详解
SVN服务器搭建和使用(一) Subversion是优秀的版本控制工具,其具体的的优点和详细介绍,这里就不再多说. 首先来下载和搭建SVN服务器. 现在Subversion已经迁移到apache网 ...
- Data Leakage 因果性
参考这篇: https://blog.csdn.net/jiandanjinxin/article/details/54633475 再论数据科学竞赛中的Data Leakage 存在和利用这种倒‘因 ...
- linux中du的用法
du:Disk Usage的缩写,命令功能为显示目录(或文件)所占磁盘空间的大小. 语 法:du [-abcDhHklmsSx0] [-L][-X File][--block-size=SIZE][- ...
- [Python] SQLBuilder 演示样例代码
用Python写一个SQLBuilder.Java版能够从 http://www.java2s.com/Code/Java/Database-SQL-JDBC/SQLBuilder.htm 看到. 附 ...
- MongoDB基本文件操作
MongoDB中主要的文件操作有put.get.list.search几种.能够非常方便地进行文件存储于查找,下面是一个简单的演示样例. 1.利用dd命令生成要求大小随机文件 2.使用put命令将生 ...
- 阿里巴巴天猫超市团队招聘java开发工程师
大家好,发个招聘信息:我是阿里巴巴集天猫超市开发团队的同学,我们部门目前在杭州招人,P6岗位,要求至少本科,熟悉java,spring等java开发技术,最好有互联网企业开发经验,感兴趣的可以通过我直 ...
- 记录MySQL运行的SQL
对照Oracle功能去学习Mysql总会发现亮点 Oracle中通过日志挖掘这一技能,能够找到以前运行过的全部记录: Mysql中也提供了3种方法{验证过的,我会记录详细做法} 方法1:{已验证} 记 ...
- HttpClient 模拟登录搜狐微博
http://mengyang.iteye.com/blog/575671 第一次遇到一个这样的问题,"PKIX path building failed" 异常 详解异常: ...
- 【转载】ASP.Net WebForm温故知新学习笔记:一、aspx与服务器控件探秘
开篇:毫无疑问,ASP.Net WebForm是微软推出的一个跨时代的Web开发模式,它将WinForm开发模式的快捷便利的优点移植到了Web开发上,我们只要学会三步:拖控件→设属性→绑事件,便可以行 ...