后缀自动机的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库的更多相关文章

  1. 后缀自动机----一种将字符串变成DAG的方法

    后缀自动机 (suffix automaton, SAM) 是一个能解决许多字符串相关问题的有力的数据结构.(否则我们也不会用它) 举几个例子,以下的字符串问题都可以在线性时间内通过 SAM 解决 1 ...

  2. SPOJ LCS 后缀自动机找最大公共子串

    这里用第一个字符串构建完成后缀自动机以后 不断用第二个字符串从左往右沿着后缀自动机往前走,如能找到,那么当前匹配配数加1 如果找不到,那么就不断沿着后缀树不断往前找到所能匹配到当前字符的最大长度,然后 ...

  3. [SPOJ1811]Longest Common Substring 后缀自动机 最长公共子串

    题目链接:http://www.spoj.com/problems/LCS/ 题意如题目,求两个串的最大公共子串LCS. 首先对其中一个字符串A建立SAM,然后用另一个字符串B在上面跑. 用一个变量L ...

  4. 一文读懂后缀自动机 Suffix_Automata

    原论文(俄文)地址:suffix_automata 原翻译(中文)地址:后缀自动机详解(DZYO的博客) Upd:强推浅显易懂(?)的SAM讲解 后缀自动机 后缀自动机(单词的有向无环图)--是一种强 ...

  5. 牛客多校第四场 I string 后缀自动机/回文自动机

    这个回文自动机的板有问题,它虽然能过这道题,但是在计算size的时候会出锅! 题意: 求一个字符串中本质不同的连续子串有几个,但是某串和它反转后的字符串算一个. 题解: 要注意的是,一般字符串题中的“ ...

  6. SPOJ 1811. Longest Common Substring (LCS,两个字符串的最长公共子串, 后缀自动机SAM)

    1811. Longest Common Substring Problem code: LCS A string is finite sequence of characters over a no ...

  7. SPOJ 1811 Longest Common Substring (后缀自动机第一题,求两个串的最长公共子串)

    题目大意: 给出两个长度小于等于25W的字符串,求它们的最长公共子串. 题目链接:http://www.spoj.com/problems/LCS/ 算法讨论: 二分+哈希, 后缀数组, 后缀自动机. ...

  8. BZOJ4032[HEOI2015]最短不公共子串——序列自动机+后缀自动机+DP+贪心

    题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ...

  9. 字符串数据结构模板/题单(后缀数组,后缀自动机,LCP,后缀平衡树,回文自动机)

    模板 后缀数组 #include<bits/stdc++.h> #define R register int using namespace std; const int N=1e6+9; ...

随机推荐

  1. 漫谈程序员系列:3D打印能打印出程序员吗

    首先声明,本文是一本正经的胡扯,绝不是随随便便的胡扯,请您不要随便攻击我胡说八道.我要反复星爷在<喜剧之王>里的台词:事实上.我是一本正经的喷子. 3D打印的定义 关于3D打印,以下是来自 ...

  2. Nginx学习——Nginx进程间的通信

    nginx进程间的通信 进程间消息传递 共享内存 共享内存还是Linux下提供的最主要的进程间通信方式,它通过mmap和shmget系统调用在内存中创建了一块连续的线性地址空间,而通过munmap或者 ...

  3. $ is not defined

    $ is not defined 引入Jquery的顺序不正确,要把它放在第一个引入

  4. Linux系统编程_1_文件夹读取(实现简单ls命令)

    闲来无事.随便写写,实现简单的ls命令: | 1 #include <stdio.h> | 2 #include <stdlib.h> | 3 #include <dir ...

  5. jenkins 构建一个前端web项目

    Jenkins发布web前端代码 “系统管理”“管理插件”“已安装” 检查是否有“Git plugin”和“Publish Over SSH”两个插件,如果没有,则需点击“可选插件”,找到它并安装 ...

  6. 各种常用的CDN加速服务

    各种CDN加速网址:点击此处 1.Echar <script type="text/javascript" src="http://echarts.baidu.co ...

  7. Java使用笔记之stream和sorted使用

    //对象类型stream排序List<User> users = new ArrayList<User>(){ { add(new User("a", &q ...

  8. linux下编译ffmpeg 引入外部库x264

    Found no assembler Minimum version is nasm-2.13 If you really want to compile without asm, configure ...

  9. 【转载】ASP.Net请求处理机制初步探索之旅 - Part 3 管道

    开篇:上一篇我们了解了一个ASP.Net页面请求的核心处理入口,它经历了三个重要的入口,分别是:ISAPIRuntime.ProcessRequest().HttpRuntime.ProcessReq ...

  10. QTreeWidget 的用法

    Qt QTreeWidget 新建一个Qt Widgets Application,拖拽一个Tree Widget 到 ui 界面上,最后实现的效果如下: 添加代码 //test.h //在头文件里添 ...