UVA11019 Matrix Matcher (二维AC自动机)

题目:https://vjudge.net/problem/UVA-11019

题意:
给一个 n*m大矩阵,一个 x*y小矩阵;
求小矩阵在大矩阵中出现次数。

分析:
将小矩阵按行插入Trie树中;
结尾标记val为行号;
注意有可能多行对应一个节点,因此val应为vector;
find()大矩阵中每行,若出现匹配,则标记这次匹配对应的小矩阵右上角出现的位置;
若一个位置被标记次数>=x,则为一次成功匹配。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int tmax=1e4+5;
int n,m,x,y,num;
int ch[tmax*30][30],f[tmax*30],last[tmax*30],cnt[1005][1005];
char mat[1005][1005];
vector<int> val[tmax*30];
queue<int> Q;
void insert(char *s,int line)
{
    int i,id,u=0,len=strlen(s);
    for(i=0;i<len;i++)
    {
        id=s[i]-'a';
        if(!ch[u][id]) ch[u][id]=++num;
        u=ch[u][id];
    }
    val[u].push_back(line);
    return;
}
void getfail()
{
    int i,x,u,v;
    Q.push(0);
    while(!Q.empty())
    {
        x=Q.front();
        Q.pop();
        for(i=0;i<26;i++)
        {
            u=ch[x][i];
            if(!u)
            {
                ch[x][i]=ch[f[x]][i];
                continue;
            }
            Q.push(u);
            if(x==0) continue;
            v=f[x];
            while(v&&!ch[v][i]) v=f[v];
            f[u]=ch[v][i];
            if(val[f[u]].size()==0) last[u]=last[f[u]];
            else last[u]=f[u];
        }
    }
    return;
}
void find(char *s,int line)
{
    int i,u=0,j,k,len=strlen(s+1),id;
    for(i=1;i<=len;i++)
    {
        id=s[i]-'a';
        u=ch[u][id];
        j=u;
        do{
            for(k=0;k<val[j].size();k++)
                if(line-val[j][k]+1>=1)
                    cnt[line-val[j][k]+1][i]++;
            j=last[j];
        }while(j);
    }
    return;
}
int main()
{
    int T,i,j;
    char tmp[105];
    cin>>T;
    while(T--)
    {
        for(i=1;i<=num;i++) val[i].clear();
        num=0;
        memset(ch,0,sizeof(ch));
        memset(f,0,sizeof(f));
        memset(last,0,sizeof(last));
        memset(cnt,0,sizeof(cnt));
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
            scanf("%s",&mat[i][1]);
        scanf("%d%d",&x,&y);
        for(i=1;i<=x;i++)
        {
            scanf("%s",tmp);
            insert(tmp,i);
        }
        getfail();
        for(i=1;i<=n;i++)
            find(mat[i],i);
        int ans=0;
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
                if(cnt[i][j]>=x) ans++;
        printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java Matcher是Java中的一个类,用于对字符串进行匹配操作。它是通过正则表达式来实现字符串匹配的功能。Matcher类提供了一系列方法,可以用于查找、匹配和替换字符串。 Matcher类的常用方法包括: 1. `matches()`:尝试将整个输入序列与模式进行匹配。 2. `find()`:在输入序列中查找下一个匹配项。 3. `group()`:返回与上一次匹配操作相匹配的输入子序列。 4. `start()`:返回上一次匹配操作的起始索引。 5. `end()`:返回上一次匹配操作的结束索引。 使用Matcher类需要先创建一个Pattern对象,通过Pattern对象的`matcher()`方法来创建一个Matcher对象。然后可以使用Matcher对象的方法进行字符串匹配操作。 下面是一个示例代码,演示了如何使用Matcher类进行字符串匹配: ```java import java.util.regex.Matcher; import java.util.regex.Pattern; public class MatcherExample { public static void main(String[] args) { String input = "Hello, World! This is a test string."; String pattern = "\\b\\w+\\b"; // 匹配单词 Pattern p = Pattern.compile(pattern); Matcher m = p.matcher(input); while (m.find()) { System.out.println("Match: " + m.group()); System.out.println("Start index: " + m.start()); System.out.println("End index: " + m.end()); } } } ``` 输出结果: ``` Match: Hello Start index: 0 End index: 5 Match: World Start index: 7 End index: 12 Match: This Start index: 15 End index: 19 Match: is Start index: 20 End index: 22 Match: a Start index: 23 End index: 24 Match: test Start index: 25 End index: 29 Match: string Start index: 30 End index: 36 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值