HDU 5972 Regular Number Bitset (字符串匹配shift and/or)
2017-07-24 12:50
519 查看
题意:
给一个长度为n的模式子串,子串的每个位置分别可以是一些数字,即一个位置可以被多个数字匹配。
再给定一个母串,问子串可以在哪些位置和母串匹配,并且输出匹配成功后的所有子串.
思路:
KMP ?(×)
前后状态互不包含,状态无法转移
AC自动机?(×)
模式串长1000,每个位置至多有10种状态
空间复杂度10^1000
Algorithm:shift and/or
算法原理:
同KMP维护最长可回溯前缀
M为目标串长度,N为模式串长度
对于每次更新的待匹配串做O(M)的匹配
算法的复杂度为O(N*M)
O(N*M)为什么不会超时
shift and/or 利用了bit位来存储计算单个模式状态。
对于每次更新的待匹配串做长度为M的匹配。
但机器每处理一次可以匹配机器字长个长度的bit位(32 or 64)。
严格的说,由于常数过大的影响导致每次匹配的复杂度会降至O(M/ 32 or 64)
总体的复杂度会降至O(N*M/ 32 or 64)
N 至大为 5e6 M 至大为 1e3
5e6*1e3/64=78125000<1e8
卡过
代码:
给一个长度为n的模式子串,子串的每个位置分别可以是一些数字,即一个位置可以被多个数字匹配。
再给定一个母串,问子串可以在哪些位置和母串匹配,并且输出匹配成功后的所有子串.
思路:
KMP ?(×)
前后状态互不包含,状态无法转移
AC自动机?(×)
模式串长1000,每个位置至多有10种状态
空间复杂度10^1000
Algorithm:shift and/or
算法原理:
同KMP维护最长可回溯前缀
M为目标串长度,N为模式串长度
对于每次更新的待匹配串做O(M)的匹配
算法的复杂度为O(N*M)
O(N*M)为什么不会超时
shift and/or 利用了bit位来存储计算单个模式状态。
对于每次更新的待匹配串做长度为M的匹配。
但机器每处理一次可以匹配机器字长个长度的bit位(32 or 64)。
严格的说,由于常数过大的影响导致每次匹配的复杂度会降至O(M/ 32 or 64)
总体的复杂度会降至O(N*M/ 32 or 64)
N 至大为 5e6 M 至大为 1e3
5e6*1e3/64=78125000<1e8
卡过
代码:
#include <bits/stdc++.h> using namespace std; const int MAXN=1010; const int MAXNN=5e6+100; bitset <MAXN> dight[11]; bitset <MAXN> p; char str[MAXNN]; int main(){ int n,m,k; while(scanf("%d",&n)!=-1){ //shift and for(int i=0;i<10;i++) dight[i].reset(); for(int i=0;i<n;i++){ scanf("%d",&m); for(int j=1;j<=m;j++){ scanf("%d",&k); dight[k].set(i); } } p.reset(); getchar(); gets(str); int len=strlen(str); for(int i=0;i<len;i++){ p=((p<<1).set(0))&dight[str[i]-'0']; if(p[n-1]==1){ char ch=str[i+1]; str[i+1]='\0'; puts(str+i-n+1); str[i+1]=ch; } } } }
#include <bits/stdc++.h> using namespace std; const int MAXN=1010; const int MAXNN=5e6+100; bitset <MAXN> dight[11]; bitset <MAXN> p; char str[MAXNN]; int main(){ int n,m,k; while(scanf("%d",&n)!=-1){ //shift or for(int i=0;i<10;i++) dight[i].set(); for(int i=0;i<n;i++){ scanf("%d",&m); for(int j=1;j<=m;j++){ scanf("%d",&k); dight[k].reset(i); } } p.set(); getchar(); gets(str); int len=strlen(str); for(int i=0;i<len;i++){ p=p<<1|dight[str[i]-'0']; if(p[n-1]==0){ char ch=str[i+1]; str[i+1]='\0'; puts(str+i-n+1); str[i+1]=ch; } } } }
相关文章推荐
- HDU 5716 带可选字符的多字符串匹配(ShiftAnd)
- hdu 5972---Regular Number(字符串匹配)
- [笔记-柔性字符串匹配]Shift-And与Shift-Or
- HDU 5972 Regular Number Bitset优化字符串匹配
- HDU 5972 Regular Number(Shift-And)
- HDU-5972 Regular Number(Shift-And)
- Shift And/Or字符串匹配算法
- HDU 5716 带可选字符的多字符串匹配 (shift-and)
- Regular Number 字符串匹配算法 Shift_and
- HDU 5972 Regular Number (bitset)
- shift-and(HDU 5972 && 2016ICPC大连 B: Regular Number)
- 学点字符串匹配——shiftAnd/shiftOr
- 扩展字符串匹配-Shift-And算法扩展
- HDU - 5972 Regular Number (bitset)
- hdu5716 hdu5745 shift-and字符串匹配
- hdu 5972 Regular Number(Shift-And算法)
- hdu 5972 Regular Number (bitset优化匹配) 2016大连现场赛
- hdu5972 Regular Number (bitset应用+快速匹配+shiftAnd匹配算法学习模板)
- HDU5972-bitset的应用或者shift-and
- HDU 1711(KMP)字符串匹配