KMP:字符串模式匹配
#include<iostream>
#include<cstring>
#define MAXN 1000010
using namespace std;
int next[MAXN];
int la,lb,j;
char a[MAXN],b[MAXN];
int main()
{
cin>>a+1;
cin>>b+1;
la=strlen(a+1);
lb=strlen(b+1);
for (int i=2;i<=lb;i++)
{
while(j&&b[i]!=b[j+1])
j=next[j];
if(b[j+1]==b[i])j++;
next[i]=j;
}
j=0;
for(int i=1;i<=la;i++)
{
while(j>0&&b[j+1]!=a[i])
j=next[j];
if (b[j+1]==a[i])
j++;
if (j==lb) {cout<<i-lb+1<<endl;j=next[j];}
}
for (int i=1;i<=lb;i++)
cout<<next[i]<<" ";
return 0;
}
KMP运用:
- PowerString问题,求字符串最小的周期
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAXN=1000000+500;
char str[MAXN];
int next[MAXN];
int getnext(int len)
{
int i=0,j=-1;
next[i]=j;
while (i<len)
{
if (j==-1 || str[i]==str[j]) next[++i]=++j;
else j=next[j];
}
return next[len];
}
int main()
{
while (scanf("%s",str))
{
if (str[0]=='.') break;
int len=strlen(str);
int T=len-getnext(len);
if (len%T==0) cout<<len/T<<endl;
else cout<<1<<endl;
}
return 0;
}
Manacher:求最长回文子串
#include<bits/stdc++.h>
using namespace std;
const int N=11000000+5;
const int inf=2147483647;
int cnt, len, ans = 0;
char s[N], ss[N*2];
int p[N*2];
void init(){//将每两个字符中插入一个字符
len = strlen(s), cnt = 1;
ss[0] = '!'; ss[cnt] = '#';
for(int i=0;i<len;i++)
ss[++cnt] = s[i], ss[++cnt] = '#';
}
void manacher(){
int pos = 0, mx = 0;
for(int i=1;i<=cnt;i++){
if(i < mx) p[i] = min(p[pos*2-i],mx-i);
else p[i] = 1;
while(ss[i+p[i]] == ss[i-p[i]]) p[i]++;
if(mx < i+p[i]) mx = i+p[i], pos = i;
ans = max(ans,p[i]-1);
}
}
int main(){
scanf("%s",s);
init(); manacher();
printf("%d\n",ans);
return 0;
}
字符串hash
unsigned int SDBMHash(char *str){
unsigned int hash = 0;
while (*str){
// equivalent to: hash = 65599*hash + (*str++);
hash = (*str++) + (hash << 6) + (hash << 16) - hash;
}
return (hash & 0x7FFFFFFF);
}
字符串全排列
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool IsSwap(char* pBegin, char* pEnd)
{
char *p;
for (p = pBegin; p < pEnd; p++)
{
if (*p == *pEnd)
return false;
}
return true;
}
void sawp(char* s1, char* s2)
{
char temp = *s1;
*s1 = *s2;
*s2 = temp;
}
void Permutation(char* pstr, char* pBegin)
{
if (*pBegin == '\0') {
static int num = 0;
num++;
cout << "第" << num << "个全排列" << pstr << endl;
//printf("%s\n", pstr);
}
else {
for (char* pCh = pBegin; *pCh != '\0'; ++pCh)
{
if (IsSwap(pBegin, pCh)) {
sawp(pBegin, pCh);
Permutation(pstr, pBegin + 1);
sawp(pBegin, pCh);
}
}
}
}
void permutation(char *str)
{
if (str == NULL)
{
return;
}
Permutation(str, str);
}
int main()
{
char a[64];
int n;
cin >> a;
n = strlen(a) - 1;
permutation(a);
system("pause");
return 0;
}
BM:字符串匹配
#include<iostream>
#define MAX 200
using namespace std;
void get_dist(int *dist,char *t,const int lenT)
{
int i;
for(i=0;i<=MAX;i++)
dist[i] = lenT;
for(i=0;i<lenT;i++)
dist[(int)t[i]] = lenT-i-1;
}
//
int BM(char *s,char *t,int *dist,const int lenS,const int lenT)
{
int i,j,k;
i = lenT-1;
while(i<lenS)
{
j = lenT-1;
k = i;
while(j>=0&&s[k]==t[j])
{
j--;
k--;
}
if(j<0)
return i+2-lenT;
else
i = i + dist[s[k]];
}
if(i>=lenS)
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
int cases;
char s[MAX],t[MAX];
int dist[MAX];
cout<<"请输入案例的个数:";
cin>>cases;
while(cases--)
{
cout<<"请输入主串:"<<endl;
cin>>s;
int lenS = strlen(s);
while(1)
{
cout<<"请输入需要匹配的模式串(以0结束):"<<endl;
cin>>t;
if(!strcmp(t,"0"))
break;
int lenT = strlen(t);
get_dist(dist,t,lenT);
int pos = BM(s,t,dist,lenS,lenT);
if(pos==0)
cout<<"没有匹配项!"<<endl;
else
cout<<"匹配的开始位置为:"<<pos<<endl;
}
}
system("pause");
return 0;
}