[ 数据结构 ] 串应用- 计算一个串的最长的真前后缀
2017-10-17 20:01
239 查看
问题 Q: 串应用- 计算一个串的最长的真前后缀
时间限制: 1 Sec 内存限制: 128 MB提交: 458 解决: 280
[提交][状态][讨论版]
题目描述
给定一个串,如ABCDAB,则 ABCDAB的真前缀有:{ A, AB,ABC, ABCD, ABCDA } ABCDAB的真后缀有:{ B, AB,DAB, CDAB, BCDAB } 因此,该串的真前缀和真后缀中最长的相等串为AB,我们称之为该串的“最长的真前后缀”。 试实现一个函数string matched_Prefix_Postfix(string str),得到输入串str的最长的真前后缀。若不存在最长的真前后缀则输出empty输入
第1行:串的个数 n 第2行到第n+1行:n个字符串输出
n个最长的真前后缀,若不存在最长的真前后缀则输出empty。样例输入
6a
ab
abc
abcd
abcda
abcdab
样例输出
emptyempty
empty
empty
a
ab
提示
// 普通方法 #include <iostream> #include <string> #include <cstring> #define rep(i, n) for ( int i = (n); i >= 1; i-- ) using namespace std; const int maxn = 1e3 + 5; string s1[maxn], s2[maxn]; void GetPrefixSuffix (string str) { int len = (int)str.size(); rep(i, len - 1) //前(后)缀的最长长度是字符串长度减 1,前(后)缀的最短长度是 1 { s1[i] = str.substr(0, i); //得到前缀的字符串数组 s2[i] = str.substr(len - i, i); //得到后缀的字符串数组 // cout << "test: " << s1[i] << endl << s2[i] << endl; } // 按照我对 rep 循环的定义,2个字符串数组,都是先截取较长的子串 } string matched_Prefix_Postfix(string str) { int len = (int)str.size(); GetPrefixSuffix(str); rep(i, len - 1) { if (s1[i] == s2[i]) return s1[i]; } return "empty"; } int main () { int t; string str; cin >> t; while (t--) { cin >> str; cout << matched_Prefix_Postfix(str) << endl; } return 0; }
/* 改进方法: 采用了 KMP 中,对next数组进行计算的思想 为什么可以结合 KMP? 因为在KMP计算next数组的递推式的定义中,采用的就是: next[k+1]= 满足下式的最大k值: p0 p1 p2 ... pk-1 = pj-k pj-k+1 pj-k+2 ... pj-1 再结合题目中对于前缀、后缀的定义, 式子左边表示的,就是字符串中,下标[0,k]的子串的所有可能前缀 同理,式子右边表示的,就是下标[0,k]的子串的所有可能后缀 所以,假设某一个字符串的长度为 len,则其下标范围为[0, len-1] 则这串字符串的前缀后缀公共部分的最长长度为 next[len],所以next数组的大小,应该比字符串的长度还要开大一位 并且,计算出的 next[len],就是我们想求的答案 因此,这题也不能完全照搬 next数组的计算,而是应该比传统的方法,再多向后计算一个 next数组的值 反正就是,如果字符串的长度为 len,那么next的数组的值需要算 (len+1)个,下标范围为 [0, len] */
#include <iostream> #include <string> using namespace std; int* GetNext (string str) { int j, k; int len = (int)str.size(); int* next = new int[(int)str.size() + 1]; j = 0; k = -1; next[j] = k; while (j < len) { if ( k == -1 || str[k] == str[j] ) { ++j; ++k; next[j] = k; } else k = next[k]; } return next; } string matched_Prefix_Postfix(string str) { int *next = GetNext(str); int ans = next[(int)str.size()]; delete[]next; if (ans <= 0) return "empty"; return str.substr(0, ans); } int main() { int t; string s; cin >> t; while (t--) { cin >> s; cout << matched_Prefix_Postfix(s) << endl; } return 0; }
相关文章推荐
- 数据结构::如何计算后缀表达式--栈的一个小应用
- 数据结构-栈应用(中缀转后缀并计算结果)
- 数据结构—中缀表达式转后缀表达式算法及实现—栈的应用—计算表达式(C++代码实现)(1)
- 数据结构学习笔记2——栈用栈计算后缀(postfix)表达的完整代码
- poj 3882 后缀数组 求一个串至少出现k次的最长重复子串的长度
- 栈应用 - 后缀表达式的计算
- 栈应用——中缀转后缀+后缀计算
- 【数据结构】栈的应用---四则运算表达式求值(中缀表达式与后缀表达式转换)
- 栈应用(中缀表达式转后缀表达式并计算后缀表达式的值)
- java中的栈Stack的基本使用和应用(二) ——利用栈计算合法的算术表达,中缀表达式转后缀表达式
- 栈的应用:中缀和后缀表达式的转换及计算
- 栈应用(中缀表达式转后缀表达式并计算后缀表达式的值)
- 【数据结构】用栈实现对后缀表达式的计算
- 查找一段文字中最长的重复字串 - 编程珠玑(排过序的后缀数组的应用)
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java) (转载)
- java 栈的实现以及栈的典型应用--字符平衡,中缀转后缀,后缀计算,迷宫求解等
- 查找一段文字中最长的重复字串 - 编程珠玑(排过序的后缀数组的应用)
- 数据结构应用--计算文件的MD5
- python数据结构与算法 8栈的应用之中缀前缀后缀
- 后缀数组的应用:最长重复(or回文)子串