目錄迴圈串字典序
給定字串s,可進行左移操作,求最小(大)字典序及其最小運算元(或有幾個最小字典序,給出所有左移運算元等)。也可用來進行迴圈串計數。
char s[maxn];
int nex[maxn];
int cal_minlex()
return;
}char t[maxn+maxm];
int kmp()
v.push_back(si);
(2)求所有前字尾,即t既是s字首,又是s字尾:
最長是s,次長是\(nex[si-1]\),然後\(i\)跳至\(nex[si-1]\),求i最長\(nex[i]\),其字尾也是\(nex[si-1]\)字尾,以此類推。
cal_next(s, si);
int i=si-1;
v.clear();
v.push_back(si);
while(i>0 && nex[i]>0)
for(int i=(int)v.size()-1; i>=0; i--)
printf("%d ", v[i]);
(3)統計每個字首的出現次數:
字首來自s且尋找s中的匹配數
若\(nex[i]>0\),則\(nex[nex[i]-1]\)一定為以\(s[i]\)結尾的次長字首,以此類推。
memset(ans, 0, sizeof(ans));
for(int i=0; i0; i--) ans[nex[i]-1]+=ans[i];//加上字尾的字首
for(int i=0; i<=si; i++) ans[i]++;//加上自己
字首來自s且尋找t中的匹配數
類似kmp構造s+#+t即可,只關注\(i\geq n+1\)的\(nex[i]\),且最後\(ans\)不用再加1。
(4)統計本質不同的子串數目(連續的):
下面求字串s新增乙個新字元c後,可新增的字串。令t=s+c,反轉得到\(t^\),計算\(t^\)的\(\max(nex[i])\),即最長的出現在s中的字首其長度,且所有更短的字首也出現了。 因此,新增c後新增字串為\(|s|-nex_+1\),其中1為字串t。\(o(n)\)
總複雜度\(o(n^2)\)。
同理,可以計算在頭部新增乙個字元,或者從尾或者頭移除乙個字元時的本質不同子串數目。 當然,移除的變化數目等於新增的變化數目。
多字串匹配:
列舉字首,o(min(si)*sum(si))
#define maxn 213
#define maxm 213
#define inf 426
int nex[maxn+maxm];
char s[maxn], a[4013][maxm];
void cal_next(char s, int si)
return;
}int kmp(int st, int x)
else if(res==ans)
} if(ans<=0) printf("identity lost\n");
else
} return 0;
}
exkmpz函式:\(z[i]\)為滿足從位置\(i\)開始且為\(s\)字首的字串的最大長度。從0開始就是\(s\)與\(s[i,n-1]\)的最長公共字首(lcp),\(aaaaa\)是\(04321\)可以超過\(i\)的,並不是只匹配\([0,i)\),\(ababa\)為\(00301\)。
int z[maxn];
void exkmp(char s, int si)
}
manacher馬拉車:在字串\(s\)中尋找最長回文連續子串。實際在\(o(n)\)找出以各個\(s[i]\)為中心的半徑。
//使長度變為基數
char s_new[maxn*2];
int p[maxn*2];
int init()
s_new[j] = '\0';//$對應\0
return j;
}int manacher()
return max_len;
}//s從s[0]開始讀入
ac自動機
給出\(n\)個\(s\),求\(a\)中能匹配多少種\(s\),\(o(sun(s.si)+a.si)\)。
只輸出種數:
允許有相同的\(s\),res+=2
#include #define maxn 500013 //sum(s.si)
#define maxm 1000013 //max(s.si, a.si)
using namespace std;
struct ac
void insert(char *s)
e[u]++;
} queueq;
void build()
} }int query(char *t)
} return res;
}};ac ac;
char s[maxm];
int n;
int main()
ac.build();
scanf("%s", s+1);
printf("%d\n", ac.query(s));
} return 0;
}
輸出每種\(s\)的匹配數:
僅有注釋部分有修改,該query()返回最大的匹配數
不允許有相同的\(s\),val[i]中存的以i結束的s(唯一)被匹配的次數
cnt[i]存s[i]的次數
aa被aaaaa匹配4次,而不是2次
#include #define maxn 83 //(s.si)
#define maxm 1000013 //max(s.si, a.si)
#define n 163 //cnt(s)
using namespace std;
struct ac
void insert(char *s, int id)
//e[u]++;
e[u]=id;//以u結束的是第id個s(前提要沒有相同的s)
} queueq;
void build()
} }int query(char *t)
} for(int i=0; i<=tot; i++)
return res;
}};ac ac;
char s[n][maxn], t[maxm];
int n;
int main()
ac.build();
scanf("%s", t+1);
int res=ac.query(t);
printf("%d\n", res);
} return 0;
}
多行字串 模板字串
多行字串 下面是普通字串的寫法 普通字串 var l abcd console.log l 編譯結果 如何讓讓乙個字串獨佔多行呢?就需要用到es6 裡的多行字串 多行字串 var i ab cd console.log i 編譯結果 再說說拼接字串,一般情況我們是如何拼接字串的呢?看下面 正常拼接字...
模板 字串 字串匹配
計算next陣列的方法是對於長度為n的匹配串,從0到n 1位依次求出字首字尾最大匹配長度。下面的寫法是僅僅檢測有沒有匹配然後返回第乙個匹配位置,而不是返回所有匹配位置。include include include using namespace std const int n 100 char s...
字串模板
include include include include using namespace std const int maxn 1e6 7 int next maxn string s,t void get next string str void kmp intmain include in...