2017ACM暑期多校联合训练 - Team 9 1010 HDU 6170 Two strings (dp)

本文介绍了一种用于判断两个字符串是否匹配的算法。该算法能够处理包含特殊符号(如 '.' 和 '*')的模拟串,并通过动态规划的方法实现了高效的匹配过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

Problem Description
Giving two strings and you should judge if they are matched.
The first string contains lowercase letters and uppercase letters.
The second string contains lowercase letters, uppercase letters, and special symbols: “.” and “”.
. can match any letter, and
means the front character can appear any times. For example, “a.b” can match “acb” or “abb”, “a” can match “a”, “aa” and even empty string. ( “” will not appear in the front of the string, and there will not be two consecutive “*”.

Input
The first line contains an integer T implying the number of test cases. (T≤15)
For each test case, there are two lines implying the two strings (The length of the two strings is less than 2500).

Output
For each test case, print “yes” if the two strings are matched, otherwise print “no”.

Sample Input
3
aa
a
abb
a.

abb
aab

Sample Output
yes
yes
no

题意:

给定两个字符串,一个是主串,另一个模拟串,主串中只含有大小写字符,模拟串中除了含有大小写字符外,还有'.'和'','.'可以与主串中的任意的字符匹配,''可以将它前面的一个字符扩展或则删去,问这两个字符串是否能够匹配成功。

分析:
str表示主串,str1表示模拟串,可以假设dp[i][j]表示str1[1,i]与str[1,j]是否匹配。
显然dp[0][0] = true,都没有开始的时候默认是匹配的。

如果 str1[i] == . 或者str1[i] == str[j]时,dp[i][j] 的状态取决于状态dp[i-1][j-1]

如果str1[i] == ‘*‘时,因为这个字符可以可以延伸或则删除前一个 dp[i][j] == dp[i-1][j] | dp[i-2][j],

而当(dp[i-1][j-1] || dp[i][j-1]) && str[j-1] == str[j] 时,dp[i][j]必定为true;

具体的看一下代码把:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 2510;
char str[N], str1[N];
bool dp[N][N];
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        memset(dp, false, sizeof(dp));
        scanf("%s %s",str+1, str1+1);
        int len = strlen(str+1), len1 = strlen(str1+1);
        dp[0][0] = true;
        for(int i = 1; i <= len1; i ++)
        {
            if(i == 2 && str1[i] == '*') dp[i][0] = true;///这样的话相当于完全可以将模拟串之前的全部去掉
            for(int j = 1; j <= len; j ++)
            {
                if(str1[i] == '.' || str1[i] == str[j])///模拟串是点或者模拟串与主串的字符相等,匹配与否取决于每个串前一个字符
                    dp[i][j] = dp[i-1][j-1];
                else if(str1[i] == '*')///模拟串是’*‘的话
                {
                    dp[i][j] = dp[i-2][j] | dp[i-1][j];///模拟串看前一个是否与祖串匹配,或则去掉前一个之后是否与祖串匹配
                    if((dp[i-1][j-1] || dp[i][j-1]) && str[j-1] == str[j])///主串的当前位置与前一个位置相等,只要前面的位置匹配或者
                        dp[i][j] = true;
                }
            }
        }
        printf("%s\n",dp[len1][len]?"yes":"no");
    }
    return 0;
}

转载于:https://www.cnblogs.com/cmmdc/p/7416646.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值