hdu6170 Two strings (DP)

 

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

题意:题意:第一段是只有字母的字符串,第二段是有字母以及特殊字符的字符串,'.'可以代替任意字符,'*'可以使它前一位的字符出现任意次数,甚至是0次(0次就代表着删掉*前面那个字符嘛),问两串字符串是否匹配。

思路:我们假设s1是先输入的字符串,s2是后输入的字符,dp[i][j] 表示s2的前i个元素和s1的前j个元素的匹配情况,匹配则1,不匹配则0;定好规矩之后,我们就开始讨论各种情况

(1)当s2[i]='.'或者等于与s1[j]匹配的字符,这时肯定是匹配的,所以 dp[i][j]=dp[i-1][j-1];

(2)当s2[i]为'*',比较复杂,咱们先一个个看

    a.如果i是在第二位,单独将dp[2][0]置1;因为此时若把*前面的元素删除,就和dp[0][0]一样了嘛

    b.如果第i-2个元素和s1中的第j个元素匹配。那么可以把*和它前面的元素删除,字符串也就匹配了。如:a - ab*

    c.如果第i-1个元素和s1中的第j个元素匹配,那么就只保留*前面的元素,也就是只删除了*,也匹配。如:ab-ab*

    d.如果第i个元素和第j-1个元素匹配,且s1[j]==s1[j-1],这时候需要将*赋值成它前面的元素,也匹配如:abb-ab*

     注意:这里为什么不是第i-1个和第j-1个呢,因为第i-1个就不是*了,所以肯定会产生不匹配的情况,如accc-ac*,答案应该是yes,但是如果改成i-1和j-1.,就会识别为no

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
 
using namespace std;
 
const int maxs=2500;
 
int dp[maxs+10][maxs+10];
 
int main()
{
    int t;
    char s1[maxs+10],s2[maxs+10];
    int i,j,l1,l2;
 
    scanf("%d",&t);
    while(t--){
		memset(dp,0,sizeof(dp));
		scanf("%s",s1+1);
		scanf("%s",s2+1);
		l1=strlen(s1+1);
		l2=strlen(s2+1);
		dp[0][0]=1;
		if(s2[2]=='*') dp[2][0]=1;	  //!!
		for(j=1;j<=l2;++j){

			for(i=1;i<=l1;++i){
				if(s1[i]==s2[j]||s2[j]=='.'){
					dp[j][i]=max(dp[j][i],dp[j-1][i-1]);
				}
				else if(s2[j]=='*'){
					dp[j][i]=dp[j-1][i]		
							 ||dp[j][i-1]&&s1[i]==s1[i-1]	   
							
							 ||dp[j-2][i];	   
				}
			}
		}
		if(dp[l2][l1]) printf("yes\n");
		else printf("no\n");
    }
 
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zvenWang/article/details/84073598