当前位置: 首页 > article >正文

【华为OD题库-063】字符匹配-java

题目

给你一个字符串数组(每个字符串均由小写字母组成)和一个字符规律(由小写字母和.和组成),识别数组中哪些字符串可以匹配到字符规律上。".“匹配任意单个字符,”*"匹配零个或多个前面的那一个元素,所谓匹配,是要涵盖整个字符串的,而不是部分字符串。
输入描述:
第一行为空格分割的多个字符串,1<单个字符串长度<100,1<字符串个数<100
第二行为字符规律,1<=字符规律长度<=50
不需要考虑异常场景
输出描述:
匹配的字符串在数组中的下标(从0开始),多个匹配时,下标升序并用,分割,若均不匹配输出-1
示例1:
输入
ab aab

.*
输出
0,1

思路

正则匹配

匹配模式加上首尾限定^$可判断是否完全匹配

动态规划

同leetcode:10. 正则表达式匹配

不利用正则匹配,使用动态规划可判断当前字符s是否和给定匹配模式p完全匹配。
dp[i][j]定义:s[:i]和p[:j]匹配是否匹配,其中s[:i]代表s的前i个字符(s[:0]代表取0个s的字符)
初始化:dp[0][0]=1,空字符串和空模式是匹配的,所以为1。考虑s为空,p=a*b*c*的模式,当p的偶数位为*时,dp[0][j]=dp[0][j-2]
递推关系:根据当前p的字符是否为*判断,只有以下情况dp[i][j]才可能为1(标黄色部分匹配即可)
如果p[j-1]== *
dp[i][j - 2] == 1,如s= a ; p= a b*
dp[i-1][j] == 1&&s[i-1]==p[j-2],如s= abb ; p= ab*
dp[i-1][j] == 1&&‘.’==p[j-2],如s= abb ; p= a.*
如果p[j-1]!= *
dp[i-1][j-1] == 1&&‘.’==p[j-1],如s= ab ; p= a.
dp[i-1][j-1] == 1&&s[i-1]==p[j-1],如s= ab ; p= ab

题解

package hwod;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class StrMatch {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] strArr = sc.nextLine().split(" ");
        String p = sc.nextLine();
        List<Integer> res = strMatch2(strArr, p);
        if (res.size() == 0) {
            System.out.println(-1);
            return;
        }
        for (int i = 0; i < res.size(); i++) {
            if (i != 0) System.out.print(",");
            System.out.print(res.get(i));
        }

    }
    //方案一:正则匹配
    private static List<Integer> strMatch(String[] strArr, String p) {
        List<Integer> res = new ArrayList<>();
        p = "^" + p + "$";
        for (int i = 0; i < strArr.length; i++) {
            if (strArr[i].matches(p)) {
                res.add(i);
            }
        }
        return res;
    }

    //方案二:动态规划
    private static List<Integer> strMatch2(String[] strArr, String p) {
        List<Integer> res = new ArrayList<>();
        for (int i = 0; i < strArr.length; i++) {
            if (checked(strArr[i], p)) {
                res.add(i);
            }
        }
        return res;
    }

    private static boolean checked(String s, String p) {
        int m = s.length() + 1, n = p.length() + 1;
        int[][] dp = new int[m][n]; //s[:i]和p[:j]匹配
        dp[0][0] = 1;
        for (int i = 2; i < n; i += 2) {
            if (p.charAt(i - 1) == '*') dp[0][i] = dp[0][i - 2];
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (p.charAt(j - 1) == '*') {
                    if (dp[i][j - 2] == 1 //a  ab*
                            || (dp[i - 1][j] == 1 && s.charAt(i - 1) == p.charAt(j - 2)) // abb ab*
                            || (dp[i - 1][j] == 1 && p.charAt(j - 2) == '.')  // abb a.*

                    ) dp[i][j] = 1;
                } else {
                    if ((dp[i - 1][j - 1] == 1 && p.charAt(j - 1) == '.') // ab a.
                            || (dp[i - 1][j - 1] == 1 && p.charAt(j - 1) == s.charAt(i - 1)) //ab ab

                    ) dp[i][j] = 1;
                }
            }
        }
        return dp[m - 1][n - 1] == 1;
    }
}


推荐

如果你对本系列的其他题目感兴趣,可以参考华为OD机试真题及题解(JAVA),查看当前专栏更新的所有题目。


http://www.kler.cn/a/162445.html

相关文章:

  • 【FFmpeg】FFmpeg 函数简介 ③ ( 编解码相关函数 | FFmpeg 源码地址 | FFmpeg 解码器相关 结构体 和 函数 )
  • 学习记录:js算法(九十二):克隆图
  • 今日 AI 简报 | 开源 RAG 文本分块库、AI代理自动化软件开发框架、多模态统一生成框架、在线图像背景移除等
  • NVIDIA Isaac Sim 仿真平台体验测评
  • ISAAC SIM踩坑记录--ubuntu 22.04操作系统安装
  • 什么是RAG? LangChain的RAG实践!
  • 『CV学习笔记』轻量化卷积神经网络MobileNet从V1到V3
  • 手机充电器市场分析:预计2028年将达到82亿美元
  • 探索人工智能领域——每日20个名词详解【day11】
  • oracle与sqlsever的区别
  • android项目实战之使用框架 集成多图片、视频的上传
  • 【无线网络技术】——无线局域网(学习笔记)
  • Github与Gitlab
  • C# 语法笔记
  • C++ 关于结构体struct的一些总结
  • 几何尺寸智能测量仪为您带来经济效益提升
  • 喝酒谁先倒
  • 【五分钟】熟悉python列表和元组的异同点【看这篇够用!建议收藏】
  • 极简模式,助力宏观数据监控
  • 图片和文字如何生成一个二维码?图文生成二维码的做法
  • 万界星空科技MES---制造企业的加工生产模式
  • Meta Platforms推出Imagine:基于Emu的免费AI文本到图像生成器服务
  • 【Linux】stat命令使用
  • 【EMNLP 2023】基于知识迁移的跨语言机器阅读理解算法
  • 【Linux系统化学习】命令行参数 | 环境变量的再次理解
  • springboot快速入门