HDU - 6170 Two strings

Two strings


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
 


题意:看两个字符串能不能匹配,点匹配任意字符,*匹配任意个数的前面一个字符,或者变为空串。


解题思路:动态规划,类似最长公共子序列,不过状态转移复杂很多,对每一种情况都要考虑。设dp[i][j]为A前i个与B前i个能否匹配。当A[i]==B[j]或B[j]=='.'时,可以匹配,所以dp[i][j]=dp[i-1][j-1],当B[j]为星号时,dp[i][j]可以从dp[i][j-1],即把*号忽略,dp[i][j-2]即把星号与前面一个字符变为空串转移过来。当a[i]==a[j-1]时,可以把*号当做前面一个字符,实际上就是看看之前的状态能否转移过来。详细看代码……注释写的很清楚了。


#include<iostream>
#include<deque>
#include<memory.h>
#include<stdio.h>
#include<map>
#include<string>
#include<algorithm>
#include<vector>
#include<math.h>
#include<stack>
#include<queue>
#include<set>
#define INF 1<<29
using namespace std;

const int N = 2505;
bool dp[N][N];

string a,b;

int main(){
    int t;
    scanf("%d",&t);
    while(t--){

        cin>>a>>b;

        a="@"+a;
        b="@"+b;//让下标从1开始

        memset(dp,0,sizeof(dp));

        dp[0][0] = true;//第一个字符相同,所以匹配

        /*处理空串情况

          @
          @a*
          这样子也是可以匹配的
         */

        if(b[2]=='*')
            dp[0][2]=1;

        for(int i=1;i<=a.size()-1;i++){

            for(int j=1;j<=b.size()-1;j++){

                if(a[i]==b[j])//如果相同,那么匹配,状态为前面的状态
                    dp[i][j]=dp[i-1][j-1];

                if(b[j]=='.')//如果为点,那么匹配,状态为前面的状态
                    dp[i][j]=dp[i-1][j-1];

                if(b[j]=='*'){

                    dp[i][j]=dp[i][j-2]||dp[i][j-1];//如果是星号,状态为,使a*变为空串或者使a*变为a
                    /*就是这种情况
            
                      aa    
                      aab     
                      是可以转移到
                      aa
                      aab*
                      
                      或
                      
                      aab    
                      aab     
                      是可以转移到
                      aab
                      aab*
                      
                     */
                    

                    if(a[i]==a[i-1])//相同的话看一下之前的一个状态能不能匹配
                        dp[i][j]=dp[i-1][j]||dp[i-1][j-1];
                    
                    /*就是这两种情况
            
                      aab     aab
                      aab     aab*
                      是可以转移到
                      aabb
                      aab*
                     */
                }
            }
        }

        if(dp[a.size()-1][b.size()-1])
            puts("yes");
        else
            puts("no");

    }
    return 0;
}








评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值