用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; ...
随机推荐
- PCA原理
http://blog.csdn.net/shizhixin/article/details/51181379
- pandas常用操作
删除某列: concatdfs.drop('Unnamed: 0',axis=1) 打印所有列名: .columns
- 雪习新知识:Java 内部类
本文出自 http://blog.csdn.net/zhaizu/article/details/49176543,转载请注明出处. 嵌套类,内部类,静态内部类,静态嵌套类.匿名类,成员类,局部类,傻 ...
- ie下div模拟的表格,表头表体无法对齐
现象:ie下,如果某个区域滚动显示表格内容(div模拟的table),表体出现滚动条的时候,会跟表头无法对齐. 解决方法:1.首先需要知道两个高度:表体最大高度height1.目前表体要显示的内容高度 ...
- Java中执行存储过程和函数
装载于:http://www.cnblogs.com/liunanjava/p/4261242.html 一.概述 如果想要执行存储过程,我们应该使用 CallableStatement 接口. Ca ...
- WinForm搭载ScintillaNET时文本由于发生偏移被隐藏解决方案
项目用ScintillaNet搭载到WinForm以满足文本编辑的需求,在用FindReplace.Scintilla.Text=“显示内容”输出文本内容的时候会碰到文本被WinForm边框隐藏的情况 ...
- hdu 1068 Girls and Boys 二分图的最大匹配
题目链接:pid=1068">http://acm.hdu.edu.cn/showproblem.php? pid=1068 #include <iostream> #in ...
- XJTU Summer Holiday Test 1(Divisibility by Eight-8的倍数)
C - Divisibility by Eight Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & ...
- WebStorm 常用功能
WebStorm 常用功能的使用技巧分享 WebStorm 是 JetBrain 公司开发的一款 JavaScript IDE,使用非常方便,可以使编写代码过程更加流畅. 本文在这里分享一些常用功能的 ...
- linux lamp
1. 用yum安装Apache,Mysql,PHP. 1.1安装Apache yum install httpd httpd-devel 安装完成后,用/etc/init.d/httpd start ...