题意:给出两个字符串s1,s2,求s2在s1中的出现的子串,输出其起始位置和长度,按长度从大到小,位置从小到大排序输出,忽略重叠的子串

代码如下:

#include <iostream>
#include <string>
#include <fstream>
#include <cstring>
#include <vector>
#include <algorithm>using namespace std;const int N = 256;
const int MIN = 0x3f3f3f3f;
const int MAXN = 100010;class SuffixArray
{
public:SuffixArray(int* pa, int n);~SuffixArray();void buildSa();void getHeight();const int* getSa();const int* getH();
private:int *m_prank;int *m_pheight;int *m_psa;int m_n;int* m_a;
};SuffixArray::SuffixArray(int* pa, int n):m_prank(NULL), m_pheight(NULL),  m_psa(NULL)
{m_a = pa;m_n = n;
}SuffixArray::~SuffixArray()
{delete []m_prank;delete []m_psa;delete []m_pheight;
}void SuffixArray::buildSa()
{m_prank = new int[m_n];int n = max(N, m_n);int* tmp = new int[m_n];int* c = new int[n];m_psa = new int[m_n];m_pheight = new int[m_n];memset(c, 0, sizeof(int) * n);for (int i = 0; i < m_n; i++){m_prank[i] = m_a[i];c[m_prank[i]]++;}for (int i = 1; i < n; i++){c[i] += c[i - 1];}for (int i = m_n - 1; i >= 0; i--){m_psa[--c[m_prank[i]]] = i;}int m =  m_n;for (int i = 1; i <= m_n; i <<= 1) {int p = 0;for (int j = m_n - i; j < m_n; j++){tmp[p++] = j;}for (int j = 0; j < m_n; j++){if (m_psa[j] >= i){tmp[p++] = m_psa[j] - i;}}memset(c, 0, sizeof(int) * n);for (int j = 0; j < m_n; j++){c[m_prank[tmp[j]]]++;}for (int j = 1; j < n; j++){c[j] += c[j - 1];}for (int j = m_n - 1; j >= 0; j--){m_psa[--c[m_prank[tmp[j]]]] = tmp[j];}swap(m_prank, tmp);m_prank[m_psa[0]] = 0;m = 0;for (int j = 1; j < m_n; j++){if (tmp[m_psa[j - 1]] == tmp[m_psa[j]] && m_psa[j- 1] + i < m_n && m_psa[j] + i < m_n && tmp[m_psa[j - 1] + i] == tmp[m_psa[j] + i]){m_prank[m_psa[j]] = m;}else {m_prank[m_psa[j]] = ++m;}}if (m >= m_n - 1) break;}delete []c;delete []tmp;return;
}void SuffixArray::getHeight()
{m_pheight[0] = 0;int k = 0;for (int i = 0; i < m_n; i++){int curPos = m_prank[i];if (curPos == 0) continue;curPos--;int j = m_psa[curPos];if (k){k--;}while (i + k < m_n && j + k < m_n && m_a[i + k] == m_a[j + k]) k++;m_pheight[m_prank[i]] = k;}
}const int* SuffixArray::getSa()
{return m_psa;
}const int* SuffixArray::getH()
{return m_pheight;
}class Result
{
public:int len, pos;bool operator < (const Result& other) const{if (len != other.len){return len > other.len;}return pos < other.pos;}
};int a[MAXN];int main(int argc, char **argv)
{
#ifndef ONLINE_JUDGEifstream fin("f:\\OJ\\uva_in.txt");streambuf* old = cin.rdbuf(fin.rdbuf());
#endifint k;int testCase = 0;while (cin >> k){if (0 == k){break;}string tdpCode, jcnCode, tmp;getline(cin, tmp);getline(cin, tmp);while (getline(cin, tmp)){if ("END TDP CODEBASE" == tmp){break;}tdpCode += tmp;tdpCode += "\n";}getline(cin, tmp);while (getline(cin, tmp)){if ("END JCN CODEBASE" == tmp){break;}jcnCode += tmp;jcnCode += "\n";}string str = jcnCode + tdpCode;int tdpCodeLen = tdpCode.length();for (int i = 0; i < tdpCodeLen; i++){a[i] = tdpCode[i];}a[tdpCodeLen] = N - 1;int jcnCodeLen = jcnCode.length();for (int i = 0; i < jcnCodeLen + 1; i++){a[tdpCodeLen + i + 1] = jcnCode[i];}SuffixArray suffixArray(a, tdpCodeLen + jcnCodeLen + 1);suffixArray.buildSa();suffixArray.getHeight();const int* psa = suffixArray.getSa();const int* pheight = suffixArray.getH();int saLen = tdpCodeLen + jcnCodeLen + 1;int* pCnt = new int[jcnCodeLen];memset(pCnt, 0, sizeof(int) * jcnCodeLen);int minVal = -1;for (int i = 0; i < saLen; i++){if (psa[i] < tdpCodeLen){minVal = MIN;}else if (psa[i] > tdpCodeLen){if (-1 == minVal){continue;}minVal = min(pheight[i], minVal);pCnt[psa[i] - 1 - tdpCodeLen] = max(pCnt[psa[i] - 1 - tdpCodeLen], minVal);}}minVal = -1;for (int i = saLen - 1; i >= 0; i--){if (psa[i] < tdpCodeLen){minVal = MIN;}else if (psa[i] > tdpCodeLen){if (-1 == minVal){continue;}minVal = min(pheight[i + 1], minVal);pCnt[psa[i] - 1 - tdpCodeLen] = max(pCnt[psa[i] - 1 - tdpCodeLen], minVal);}}vector<Result> result;int curPos = -1;for (int i = 0; i < jcnCodeLen; i++){if ((i + pCnt[i] <= curPos) || pCnt[i] <= 0) continue;result.push_back((Result){pCnt[i], i});curPos = i + pCnt[i];}delete []pCnt;sort(result.begin(), result.end());if (testCase){cout << endl;}cout << "CASE " << ++testCase << endl;for (int i = 0; i < min(k, (int)result.size()); i++){cout << "INFRINGING SEGMENT " << i + 1 << " LENGTH " << result[i].len << " POSITION " << result[i].pos << endl;cout << jcnCode.substr(result[i].pos, result[i].len) << endl;}}#ifndef ONLINE_JUDGEcin.rdbuf(old);
#endif
}

UVa10526 - Intellectual Property(后缀数组的应用)相关推荐

  1. UVA 10526 - Intellectual Property (后缀数组)

    UVA 10526 - Intellectual Property 题目链接 题意:给定两个问题,要求找出第二个文本抄袭第一个文本的所有位置和长度,输出前k个,按长度从大到小先排,长度一样的按位置从小 ...

  2. 寻找一个字符串的重复子串 后缀数组

    什么是后缀数组 令字符串 S=S[1]S[2]...S[n]S=S[1]S[2]...S[n]{\displaystyle S=S[1]S[2]...S[n]} , S[i,j]S[i,j]{\dis ...

  3. 【2012百度之星/资格赛】H:用户请求中的品牌 [后缀数组]

    时间限制: 1000ms 内存限制: 65536kB 描述 馅饼同学是一个在百度工作,做用户请求(query)分析的同学,他在用户请求中经常会遇到一些很奇葩的词汇.在比方说"johnsonj ...

  4. Boring counting HDU - 3518 (后缀数组)

    Boring counting \[ Time Limit: 1000 ms \quad Memory Limit: 32768 kB \] 题意 给出一个字符串,求出其中出现两次及以上的子串个数,要 ...

  5. HDU4080 Stammering Aliens(二分 + 后缀数组)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4080 Description Dr. Ellie Arroway has establish ...

  6. 后缀数组 + Hash + 二分 or Hash + 二分 + 双指针 求 LCP ---- 2017icpc 青岛 J Suffix (假题!!)

    题目链接 题目大意: 就是给你n个串每个串取一个后缀,要求把串拼起来要求字典序最小!! sum_length_of_n≤5e5sum\_length\_of\_n\leq 5e5sum_length_ ...

  7. 后缀数组 ---- 2018~2019icpc焦作H题[后缀数组+st表+二分+单调栈]

    题目链接 题目大意: 给出nnn个数,定义f[l,r]f[l,r]f[l,r]表示 区间[l,r][l,r][l,r]的最大值,求所有 子区间的最大值的和,要求相同的子区间只能算一次 比如数列 5 6 ...

  8. [Ahoi2013]差异[后缀数组+单调栈]

    链接 解题思路:很明显前面∑1<=i<j<=nlen(Ti)+len(Tj)\sum_{1<=i<j<=n}len(T_i)+len(T_j)∑1<=i< ...

  9. poj2217详解 ( 后缀数组 + 高度数组 )

    题目大概意思就是 给两个字符串,求最长公共字符串子串长度 我们可以考虑用后缀数组和高度数组 一个字符串 中 最长的两个相同字符串长度, 不就是 后缀数组中相邻两个后缀的最长公共前缀, 不就是 高度数组 ...

最新文章

  1. Spring常问的面试
  2. 线程间通讯机制(提高篇)——深入浅出实现原理
  3. mysql error 1148_MYSQL入坑第一弹--------ERROR 1148 (42000)ERROR 1290 (HY000)
  4. Megacli恢复RAID0磁盘数据
  5. 【格局视野】三色需求与工作层次
  6. 数据库设计指南【转】
  7. PostgreSQL判断一个表是否存在
  8. java enumset_Java EnumSet工作原理初窥
  9. mysql创建表空间和用户
  10. Google PAI资料整理及实现
  11. oracle mysql认证考试流程_oraclemysql认证考试流程
  12. KindEditor实现上传图片与回显
  13. 安全合规/法案--33--《APP违法违规收集使用个人信息自评估指南》原文及解读
  14. Mac上如何提取解压pkg文件
  15. android拼图游戏制作,[Android]自己动手做个拼图游戏
  16. 详解浪潮与Odoo联手背后 双方将带来哪些化学反应?
  17. 电脑可以联网但是有的网页打不开
  18. PCB板上的蓝宝石---关于光学定位点的DFM
  19. 雪鹰领主手游战力提升辅助攻略 雪鹰领主手游脚本工具介绍
  20. 钉钉、飞书、企业微信,还没学会赚钱

热门文章

  1. 如何用程序删除win 7下SYSTEM权限的目录
  2. Rhythmk 一步一步学 JAVA(11)Ibatis 环境配置
  3. 使用jsp:useBean指令
  4. Javascript使用Ajax跟踪历史
  5. 面向对象编程的乐趣(TextBox.Text=)
  6. 易语言基础编程知识〖E语言手册〗
  7. python导入csv文件-Python从CSV文件导入数据和生成简单图表
  8. 安卓python编辑器-有了这款编辑器,随时随地都能愉快的学习python!
  9. python手机版安卓-当python遇到Android手机 那么,万物皆可盘
  10. python读取文件夹-Python按顺序读取文件夹中文件