随笔分类 - 字符串处理
摘要:题意:求A 串中不在 所有B串中出现大不同子串的个数分析:后缀数组可以很简单的实现求一个串不同字子串的个数,,从这方面下手就很容易想到了,之前比赛的时候,,死活没想法先将所有串拼接起来,计算不包含分隔符的不同子串的个数sumAB,再单独将所有B串拼接起来,同样的方法求一遍,得到sumB,sumAB-sumB即为所求View Code #include <iostream>#include <algorithm>#include <string.h> #include <math.h>#include <string>int const
阅读全文
摘要:给定N个物种的基因序列,若俩个序列s1和s2的最长公共子串长度len满足 |s1|*p<len && |s2|*p<len (p是题目给定的百分比),则俩个物种属于同一类,问这N个物种可以分为几类分析:额,LCS+并查集View Code #include<iostream>#include<algorithm>#include<string>#include<vector>using namespace std;const int N = 100+10;int n,f[N];double p;char str[N][
阅读全文
摘要:题意:求最长回文串用Manacher 可以在O(n)时间内解决#include<iostream>#include<algorithm>#include<string.h>#define MAXN 200010using namespace std;char str1[MAXN],str[MAXN*2];int rad[MAXN*2],nn,n;void Manacher(int *rad,char *str,int n){ int i; int mx = 0; int id; for(i=1; i<n; i++) { if( mx > i )
阅读全文
摘要:题意:求多个串的最长公共子串pku3450用KMP算法#include<iostream>#include<algorithm>#include<string.h>using namespace std;int nxt[210];char str[4010][210],s[210];int n,m;bool KMP(char *T,char *P){ memset(nxt,0,sizeof(nxt)); nxt[0]=-1; int k=-1; for(int q=1;q<m;q++) { while(k>-1&& P[k+1]!
阅读全文
摘要:比较裸的KMP#include<iostream>#include<algorithm>using namespace std;int n,m;char T[1000010],P[10010];int nxt[10010];int KMP(){ nxt[0] = -1; int k = -1; for(int q=1;q<=m-1;q++){ while (k > -1 && P[k+1] != P[q]) k = nxt[k]; if (P[k+1] == P[q]) ++k; nxt[q] = k; }...
阅读全文
摘要:题意:在文本T[1..n],找一个最长的后缀(长度为m,m<=13),以这个后缀为匹配的模式P:T[n-m+1..n]找出P在文本T[1..n-1]出现的最后一个起始位置k,(k<=n-m)若找到k,则得出T[n+1]为找到的模式T[k..k+m-1]的下一个位置: 即:T[n+1] = T[k+m]如果m==13时找不到,则尝试m==12直到m==1,如果都找不到,则T[n+1] = 0;分析:* KMP* 一旦得到一个匹配之后就增加源串长度 下次找匹配 T 和 P 都会变* 因为这次匹配之后 给源串增加的那个字符就是前面相匹配的串的下一个字符* 所以至少这个位置会继续匹配下去*
阅读全文
摘要:嘿嘿,以前写的,刚刚突然看到的,就贴一下咯,KMP 的求next[]数组的活用,求最长重复字串pku2406#include <stdio.h>#include <stdlib.h>#include <string.h> char str [1000010];int next[1000010]; int getnext(){ int i= 0, j= -1; next[0]= -1; while( str[i] )//这个过程其实就是在求next[]数组 { if( j== -1 || str[i]== str[j] ) { ++i,++j; next[i]
阅读全文
摘要:郁闷死我了,求最长的回文串;本身读进来的是含有标点符号的一个文本串,之后找回文串的时候又忽略了那些标点符号,输出又要将那些标点符号输出…………蛋疼好久,幸好是可以看到什么例子没过,不过,我看是没希望过的了…………orz,文本里面的“\n”也是有效的……用前面的那个求最长回文串的算法就很容易过了,主要是 在处理那个标点符号的问题上……/*ID: nanke691LANG: C++TASK: calfflac*/#include<iostream>#include<fstream>#include<string.h>#define maxn 20010using
阅读全文
摘要:感觉这个题解挺不错的,自己理解了一下,还可以哦,哈,想不到还有这么一个O(n)的求最长回文串的算法。http://blog.sina.com.cn/s/blog_6fa65cf90100s3sg.html附上倆道的AC代码hdu3068#include<iostream>#include<algorithm>#include<string.h>#define maxn 111000using namespace std;char str[maxn],str1[maxn*2];int n,ans,nxt[maxn*2];void Manacher(){ mem
阅读全文
摘要:这倆道是一样的题目,题意就是将一个字符串转变为回文串的最少添加数有俩种方法:1.求正串和反串的最长公共子序列,再用原先串的长度相减即可;2.令c (i,j)表示将子串aiai+1…aj变成回文词的最小添加字符数。则这此问题就是要求c(1,n)。 •c(i,j)满足如下递推关系: 从代码可以看出,俩种方法的效率想差很大第一种方法#include<iostream>#include<string>#include<algorithm>using namespace std;int main(){ char s1[5010],s2[5010]; int s[2][
阅读全文
摘要:找最长的公共字串,暴搜呀,先将字符串按长度从短到长排序,枚举最短的字符串的子串,判断是否都是别的字符串的子串,求出最大长度即可什么反串之类的,其实在枚举最短字串的时候,多定义一个字符串再一起赋值就OK了,看代码吧#include<stdio.h>#include<string.h>#include<stdlib.h>char s[105][105];int main(){ int t; scanf("%d",&t); while(t--) { int n,m=100000,l; scanf("%d",&
阅读全文
摘要:真是服了自己了,一个简单的字符串替换搞了半天……………………C++还是不太会#include<iostream>#include<string>using namespace std;int main(){ string str; while(getline(cin,str)) { //getchar(); string::size_type pos = 0; string str1="you"; while ((pos=str.find(str1,pos)) != string::npos)//若查找失败,返回string::npos { str.
阅读全文
摘要:这字符串处理够麻烦的,不过居然都可以用库函数解决,倘若是手动对字符串进行预处理,真是难以想象啊不过,也不可否认,内存开了超大的,时间也差点超了…… #include<iostream> #include<string> #include<map> using namespace std; map<string, int> s; string tele[1000000]; int main() { s.clear(); int n, k = 0; cin >> n; for (int i = 1; i <= n; i++) { c
阅读全文
摘要:这题目郁闷死了,因为一些小错误,搞了半天,不过,要注意的东西真的很多哦题意是找出单词的所有符号要求的匹配模式,首先将模式存入字典树中,再用单词进行查找需要注意的问题:看到输出的sample也应该知道了,一个单词有多种匹配模式,用一个单词进行遍历时,到达同一个单词的结尾,却可能经历了不同的匹配模式,所以这里用了并查集来保存具体的,还是结合代码吧,比较好解释#include<iostream>#include<string>#include<algorithm>using namespace std;struct node{ int num;//保存模式的编号
阅读全文
摘要:额,这题,我好想看到分类说是用trie树,可是怎么想也没什么思路,就用了暴力了若找不到相同的单词,则相似的也只有三种情况代码很好理解#include<iostream>using namespace std;#define MAXN 10001char str[MAXN][20];bool replace(char *a,char *b){ int l1=strlen(a); int l2=strlen(b); if(l1==l2)//修改一个字符 { int i=0; while(i<l1&&a[i]==b[i])//找到第一个不同的字符的位置 i++; w
阅读全文