随笔分类 -  字符串

摘要:字符串DP 题意:给你三个字符串a,b,c求字符串d的长度。 字符串d满足的要求:是a和b的公共子序列,c是它的子串。 定义dp1[i][j]表示a的第 i 位与b的第 j 位之前相同的子序列长度(包括 i ,j),dp2[i][j]表示a的第 i 位与b的第 j 位之后相同的子序列长度(包括 i ,j)。 查找c的首尾字符在a 和b 的位置,求出c首字符之前a和b的公共子序列的长度以及c尾字符之后a和b的公共子序列的长度,加上c的长度即为所求。#include#include#define maxn 1010#define max(a,b) (a)>(b)?(a):(b)char... 阅读全文
posted @ 2013-08-17 14:26 yongren1zu 阅读(148) 评论(0) 推荐(0)
摘要:1.求重复子串: (1).可重叠最长重复子串 做法简单,只要求出height数组中的最大值即可。首先求最长重复子串,等价与求两个后缀数组的最长公共前缀。 (2).不可重叠最长重复子串 把排序后的后缀分成若干组,其中每组的后缀之间的height值不小于k。例如,字符串为“aabaaaab”,当k=2时,后缀分成4组,如图所示: 有希望成为最长公共前缀不小于k的两个后缀一定在同一组。然后对于每组后缀,只须判断每个后缀的sa 值的最大值和最小值之差是否不小于k。如果有一组满足,则说明存在,否则不存在。 (3).子串的个数 求不相同的子串的个数。 如果所有的后缀按 suffix... 阅读全文
posted @ 2013-08-05 22:05 yongren1zu 阅读(2316) 评论(0) 推荐(0)
摘要:height数组:定义 height[i] = suffix[i-1] 和 suffix[i] 的最长公共前缀,也就是排名相邻的两个后缀的最长公共前缀。那么对于 j 和 k 不妨设 Rank[j] =h[i-1]-1. 证明: 设suffix[k]是排在suffix[i-1]前一名的后缀,则它们的最长公共前缀是h[i-1]。那么suffix[k+1]将排在suffix[i]前面(这里要求h[i-1]>1,如果h[i-1]<=1原式显然成立)并且suffix[k+1]和suffix[i]的最长公共前缀是h[i-1]-1,所以suffix(i)和它前一位的最长公共前缀至少是h[i-1] 阅读全文
posted @ 2013-08-05 21:01 yongren1zu 阅读(812) 评论(0) 推荐(0)
摘要:暴力求解题意:求一个公共子串的最大长度,反转的公共子串存在也算。求解思路:先找出最短的字符串进行暴力枚举。每截取一个子串后,求出它的反转字符串,然后检验这两个子字符串是否存在输入的字符串组中,每个字符串只要存在子字符串和的翻转串其中一个就行。#include#include#includeusing namespace std;#define max(a,b) a>b?a:bint n,len,id;string str[110];bool check(string sub){ string tmp; int sl=sub.size(); for(int i=0;i=i;j-... 阅读全文
posted @ 2013-08-05 14:37 yongren1zu 阅读(158) 评论(0) 推荐(0)
摘要:今天看了一下后缀数组算法,感觉好NB的样子,的确不太好看~~,可能智商捉急吧~~ 后缀是字符串 r 从第 i 个字符开始到字符串结尾,后缀表示为 suffix(i)。 后缀数组:sa是一个一位数组,保存1...n的某个排列sa[1],sa[2],...,sa[n],并且保证后缀从小到大进行排序之后把排序好的后缀的开头位置依次放入sa中。 名次数组:名次数组Rank[i]保存的是suffix[i]在所有后缀中从小到大排列中的名次。 后缀数组-------排第几的是谁,名次数组------你排第几。 倍增算法:对每个字符开始的长度为2^k的子字符串进行排序,求出排名。k从0开始,每次... 阅读全文
posted @ 2013-08-04 16:54 yongren1zu 阅读(687) 评论(0) 推荐(0)
摘要:找一个字符串的最小字典排序,最小表示法返回最小字典排序首字母的下标。最小表示法的复杂度为O(n)。实现方法:(1).利用两个指针p1,p2。初始化时p1指向s[0],p2指向s[1]。(2).k=0开始,检验s[p1+k]和s[p2+k]是否相等,相等则k++,一直下去,直到找到第一个不相同的字符(若k试了一个字符串的长度也没找到不同,则那个位置就是最小表示位置,算法终止并返回)。该过程中s[p1+k]和s[p2+k]的关系有三种: 1).s[p1+k]>s[p2+k],p1滑动到p1+k+1处,s[p1--p1+k-1]不会是循环字符串的"最小表示"的前缀。 2). 阅读全文
posted @ 2013-08-03 23:18 yongren1zu 阅读(234) 评论(0) 推荐(0)
摘要:Manacher算法用于求回文子串,它的复杂度为O(n)。这个算法有一个很巧妙的地方,它把奇数的回文串和偶数的回文串统一起来考虑了。在相邻的两个字符之间加进一个分隔符 '#' ,串的首尾也要加。原串:abaab新串:#a#b#a#a#b#中心思想是,用一个辅助数组p记录以每个字符为中心的最长回文半径,也就是p[i]记录以s[i]字符为中心的最长回文半径。p[i]最小为1,此时回文串为s[i]本身。我们用MaxId记录在 i 之前的回文串中,延伸至最右端的位置,同时用id记录这个MaxId的id值。核心代码如下: for(i=1;ii) { ... 阅读全文
posted @ 2013-08-03 15:46 yongren1zu 阅读(155) 评论(0) 推荐(0)
摘要:参考博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP算法用来匹配两个字符串,即b串是否为a的子串。 普通算法的复杂度为O(n*m),KMP算法的复杂度为O(n+m)。 用 i 计数 a 串的位置,用 j 计数 b 串的位置。 普通算法: 如果 a[i] != b[j] ,则 i 回溯,j=0。 KMP算法: KMP算法和普通算法的区别在于,KMP消除的 i 的回溯,只需确定下次匹配 j 的位置即可。在KMP算法中引入了next数组,为了确定匹配不成功时,下次匹配时 j 的位置。n... 阅读全文
posted @ 2013-08-03 15:17 yongren1zu 阅读(177) 评论(0) 推荐(0)
摘要:一道dp题,转移方程不是自己推出来的。题目的意思是用‘qnmlgb’替换‘hehe’,可以替换也可以不替换,问有多少种情况。如果结尾不是‘hehe’,那么dp[i]=dp[i-1],如果是是‘hehe’,dp[i]=dp[i]+dp[i-4],因为最后一个可以换也可以不换,如果进行替换则是dp[i-4]。#include#include#define M 10007char s[10100];int dp[10100]={1};int main(){ int T,cas=1; scanf("%d",&T); while(T--) { scanf("%s&q 阅读全文
posted @ 2013-08-01 20:41 yongren1zu 阅读(175) 评论(0) 推荐(0)