zoukankan      html  css  js  c++  java
  • poj 1204 字符串处理 多串匹配自动机

    View Code
      1 #include<cstdio>
      2 #include<cstring>
      3 #include<stdlib.h>
      4 #define N 1010
      5 struct node
      6 {
      7        node *next[26];
      8        node *fail;
      9        int count,index;
     10        node()
     11        {
     12             count=0,index=0,fail=NULL;
     13             for(int i=0;i<26;i++)next[i]=NULL;
     14        }
     15 }*root,*q[501000];
     16 int head,tail;
     17 int n,m,w,sum,x[N],y[N];
     18 char map[N][N];
     19 char str[N],dir[N];
     20 int len[N];
     21 int h[8]={-1,-1,0,1,1,1,0,-1};
     22 int c[8]={0,1,1,1,0,-1,-1,-1};
     23 void insert(int ii)
     24 {
     25      int i=0,index;
     26      node *temp=root;
     27      len[ii]=strlen(str);
     28      while(str[i])
     29      {
     30            index=str[i]-'A';
     31            if(temp->next[index]==NULL)temp->next[index]=new node();
     32            temp=temp->next[index];
     33            i++;
     34      }
     35      temp->count=1;
     36      temp->index=ii;
     37 }
     38 void build_ac()
     39 {
     40      node *temp,*p;
     41      head=tail=0;
     42      q[head++]=root;
     43      while(head!=tail)
     44      {
     45            temp=q[tail++];
     46            for(int i=0;i<26;i++)
     47            {
     48                if(temp->next[i]!=NULL)
     49                {
     50                    if(temp==root)temp->next[i]->fail=root;
     51                    else
     52                    {
     53                        p=temp->fail;
     54                        while(p!=NULL)
     55                        {
     56                              if(p->next[i]!=NULL)
     57                              {
     58                                 temp->next[i]->fail=p->next[i];
     59                                 break;
     60                              }
     61                              p=p->fail;
     62                        }
     63                        if(p==NULL)temp->next[i]->fail=root;
     64                    }
     65                    q[head++]=temp->next[i];
     66                }
     67            }
     68      }
     69 }
     70 bool Is_OK(int x,int y)
     71 {
     72      if(x>=n||x<0||y<0||y>=m)
     73         return false;
     74      return true;
     75 }
     76 void query(int i,int j,int k)
     77 {
     78      int cx=i,cy=j,ind;
     79      node *temp=root,*p;
     80      for(;Is_OK(cx,cy);cx+=h[k],cy+=c[k])
     81      {
     82           ind=map[cx][cy]-'A';
     83           printf("%d\n",ind);
     84           while(temp->next[ind]==NULL&&temp!=root)
     85           {
     86                 temp=temp->fail;
     87                 
     88           }
     89           temp=temp->next[ind];
     90           p=(temp==NULL)?root:temp;
     91           while(p!=root)
     92           {
     93                 if(p->count)
     94                 {
     95                    sum++;
     96                    p->count=0;
     97                    x[p->index]=cx-(h[k]*len[p->index]);
     98                    y[p->index]=cy-(c[k]*len[p->index]);
     99                    dir[p->index]='A'+k;
    100                 }
    101                 p=p->fail;
    102           }
    103      }
    104 }
    105 void solution()
    106 {
    107      for(int i=0;i<n&&sum<w;i++)
    108      {
    109          query(i,0,1);query(i,0,2);query(i,0,3);
    110          query(i,m-1,5);query(i,m-1,6);query(i,m-1,7);
    111      }
    112      for(int i=0;i<m&&sum<w;i++)
    113      {
    114          query(0,i,3);query(0,i,4);query(0,i,5);
    115          query(n-1,i,0);query(n-1,i,1);query(n-1,i,7);
    116      }
    117 }
    118 int main()
    119 {
    120     while(~scanf("%d%d%d",&n,&m,&w))
    121     {
    122          root=new node();
    123          for(int i=0;i<n;i++)
    124              scanf("%s",map[i]);
    125          sum=0;
    126          for(int i=0;i<w;i++)
    127          {
    128              scanf("%s",str);
    129              insert(i+1);
    130          }
    131          build_ac();
    132          solution();
    133          for(int i=1;i<=w;i++)
    134              printf("%d %d %c\n",x[i],y[i],dir[i]);
    135 
    136     }
    137     return 0;
    138 }

    题意:

    告诉你一篇文章,也就是一个nxm的字符矩阵,然后给你w个单词,问这些单词在文章中出现的位置,输出坐标,然后现在有八个方向。

    同时还要在输出的坐标位置后面输出相应的匹配方向。

    为了节省时间,我们肯定首先要建立一个字典树。

    然后做法有两种,一种是直接从文章中的每一个点出发从八个方向,在字典树当中比较。

    一种是建立ac自动机,构建字典树当中的fail指针,从文章的边界出发,将所有的能匹配的方向都扫一遍就ok了。。。

    字典树做法:

    View Code
     1 #include<cstdio>
     2 #include<cstring>
     3 #define N 1010
     4 struct node
     5 {
     6        node *next[26];
     7        int count,index;
     8        node()
     9        {
    10            count=0,index=0;
    11            for(int i=0;i<26;i++)next[i]=NULL;
    12        }
    13 }*root;
    14 char map[N][N];
    15 char str[N];
    16 int n,m,w,sum;
    17 int x[N],y[N];
    18 char dir[N];
    19 int h[8]={-1,-1,0,1,1,1,0,-1};
    20 int c[8]={0,1,1,1,0,-1,-1,-1};
    21 void insert(int ii)
    22 {
    23      node *p=root;
    24      int i=0;
    25      while(str[i])
    26      {
    27            int ind=str[i]-'A';
    28            if(p->next[ind]==NULL)p->next[ind]=new node();
    29            p=p->next[ind];
    30            i++;
    31      }
    32      p->count=1;
    33      p->index=ii;
    34 }
    35 bool Is_OK(int x,int y)
    36 {
    37      if(x>=0&&x<n&&y>=0&&y<m)
    38      return true;
    39      return false;
    40 }
    41 void query(int i,int j,int k)
    42 {
    43       int cx=i,cy=j,index;
    44       node *temp=root,*p;
    45       for(;Is_OK(cx,cy);cx+=h[k],cy+=c[k])
    46       {
    47           index=map[cx][cy]-'A';
    48           if(temp->next[index]==NULL)
    49              return ;
    50           temp=temp->next[index];
    51           if(temp->count)
    52           {
    53              sum++;
    54              x[temp->index]=i;
    55              y[temp->index]=j;
    56              dir[temp->index]='A'+k;
    57              temp->count=0;
    58           }
    59       }
    60 }
    61 void solution()
    62 {
    63      for(int i=0;i<n;i++)
    64      {
    65          for(int j=0;j<m;j++)
    66          {
    67             for(int k=0;k<8;k++)
    68             {
    69                query(i,j,k);
    70                if(sum==w)break;
    71             }
    72             if(sum==w)break;
    73          }
    74          if(sum==w)break;
    75      }
    76 }
    77 int main()
    78 {
    79     while(~scanf("%d%d%d",&n,&m,&w))
    80     {
    81         root=new node();
    82         for(int i=0;i<n;i++)
    83             scanf("%s",map[i]);
    84         for(int i=0;i<w;i++)
    85         {
    86             scanf("%s",str);
    87             insert(i+1);
    88         }
    89         sum=0;
    90         solution();
    91         for(int i=1;i<=w;i++)
    92             printf("%d %d %c\n",x[i],y[i],dir[i]);
    93     }
    94     return 0;
    95 }

    ac自动机:

  • 相关阅读:
    k8s 使用 Init Container 确保依赖的服务已经启动
    asp.net core 从 3.0 到 3.1
    Github原生CI/CD,初尝Github Actions
    [nginx]编译安装及安全优化
    [nginx]盗链和防盗链场景模拟实现
    [nginx]location语法
    [nginx]站点目录及文件访问控制
    [svc]nginx限制客户端上传附件的大小
    [sql]mysql指引(整理中...)-对db的分类
    [sql]mysql参数(配置)手册
  • 原文地址:https://www.cnblogs.com/nuoyan2010/p/2939930.html
Copyright © 2011-2022 走看看