HDU5716 : 带可选字符的多字符串匹配

shift-and算法,设$v[i][j]$表示文本串长度为$i$的前缀能否匹配模式串长度为$j$的前缀,$f[i][j]$表示字符$i$能否匹配模式串的第$j$个位置,那么有$v[i+1][j+1]=v[i][j]\ and\ f[s[i+1]][j+1]$。

显然$j$这一维可以用bitset加速,时间复杂度$O(\frac{nm}{64})$。

#include<cstdio>
#include<bitset>
int n,i,j,flag;std::bitset<505>v,f[62];char s[2000010],t[99];
inline int id(char x){
  if(x>=‘a‘&&x<=‘z‘)return x-‘a‘;
  if(x>=‘A‘&&x<=‘Z‘)return x-‘A‘+26;
  if(x>=‘0‘&&x<=‘9‘)return x-‘0‘+52;
  return -1;
}
int main(){
  while(gets(s)){
    scanf("%d",&n);
    for(flag=0,i=0;i<62;i++)f[i].reset();v.reset();
    for(i=1;i<=n;i++){
      scanf("%d%s",&j,t);
      for(j=0;t[j];j++)f[id(t[j])][i]=1;
    }
    v[0]=1;
    for(i=0;s[i];i++){
      if(id(s[i])<0)v.reset();else v=v<<1&f[id(s[i])];
      v[0]=1;
      if(v[n]==1)flag=1,printf("%d\n",i-n+2);
    }
    if(!flag)puts("NULL");
    getchar();
  }
  return 0;
}
时间: 2024-10-22 06:57:09

HDU5716 : 带可选字符的多字符串匹配的相关文章

通过编写串口助手工具学习MFC过程&mdash;&mdash;(三)Unicode字符集的宽字符和多字节字符转换

通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个串口助手再次熟悉一下MFC,并做了一下记录,以便方便以后查阅.做的过程中多是遇到问题直接百度和谷歌搜索来的,所以很多都是不求甚解,知其然不知其所以然.另外做此工具只是为了熟悉了解,许多功能还没有完善!(开发工具VS2008) (三)Unicode字符集的宽字符和多字节字符转换 在上一节<(二)通过&qu

字符编码、字符存储、字符转换及工程中字符的使用

字符编码.字符存储.字符转换及工程中字符的使用 版本控制 版本 时间(北京时间) 作者 备注 V1.0 2016-05-13 施小丰 创建本文.第七章工程总结尚未完成 一.          前言 1.        目的 本文主要用于整理字符相关知识,包括字符编码.字符存储.行业标准.文件读写.工程注意事项等涉及字符相关的内容, 从而在实际工程中更好地设计和使用字符.更快地解决字符问题. 2.        适用范围 本文标题是"Windows C++字符编码.存储.转换大全", 但

删除最后结尾的指定字符后的字符

#region 删除最后结尾的指定字符后的字符 2 /// <summary> 3 /// 删除最后结尾的指定字符后的字符 4 /// </summary> 5 public static string DelLastChar(string str, string strchar) 6 { 7 if (string.IsNullOrEmpty(str)) 8 return ""; 9 if (str.LastIndexOf(strchar) >= 0 &a

字符指针与字符数组

学了挺久的c语言,c语言有意思的就有指针这一大块,另外就是字符串,字符指针与字符数组的区别对于初学者应该是比较难以区分的,讲讲自己的看法. 1.定义上的区别 字符数组具有固定的地址,且字符数组的名字不能更改或运算. 字符指针是一个变量,用来存储首字符的地址,且指向的字符串通常为一个常量. char str[] = "helloworld"; str[4] = 'X'; printf("%s",str); 输出结果:hellXworld char *str = &qu

关于C中字符数组,字符指针以及C++中string类型的两两转换及排序

// practise.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <string.h> #include <string> #include <algorithm> #include <iostream> using namespace std; int main() { /* 字符串转字符数组,使用strncpy_s(),比strncpy()安全*/ string str

LCD1602 显示数字,字符,自定义字符,字符串,光标

/******************************************* 程序名:   1602液晶屏时钟程序 编写时间: 2015年10月4日 硬件支持: LCD1602液晶屏  STC12C4052AD 外部12MHZ晶振  接线定义:  DB0_DB7 --> P1^0 --P1^7 RS   = P3 ^ 2;         RW   = P3 ^ 3;   E    = P3 ^ 4;   功能:测试LCD1602的显示,显示时间,http://990487026.b

LCD1602显示,用4位总线显示数字,字符,自定义字符,字符串,光标

/******************************************* 程序名:   1602液晶屏时钟程序 编写时间: 2015年10月4日 硬件支持: LCD1602液晶屏  STC12C4052AD 外部12MHZ晶振  接线定义: DB7 --> P1^7 DB6 --> P1^6 DB5 --> P1^5 DB4 --> P1^5 RS   = P3 ^ 2;   RW   = P3 ^ 3;   E    = P3 ^ 4;   功能:LCD1602显

统计一行字符中各类字符的个数

/*输出一行字符,分类统计字符个数*/ #include<stdio.h>#include<stdlib.h>int main(void){ int letter=0,space=0,digit=0,other=0;/*定义变量并初始化*/ char c;/*定义字符串c*/ printf("请输入一行字符,以回车键结束\n"); while((c=getchar())!='\n')/*判断c是否是回车键*/ if(c>='a'&&c<

将字符串s1中的任何与字符串s2中字符匹配的字符都删除

编写一个程序,将字符串s1中的任何与字符串s2中字符匹配的字符都删除. 函数原型:void my_squeeze(char s1[], char s2[]) #include <stdio.h> void my_squeeze(char s1[], char s2[]) { int i = 0; int j = 0; while (s2[j]) { while(s1[i]) { if (s2[j]==s1[i]) { while (s1[i+1]) { s1[i] = s1[i + 1]; i