HJ71 字符串通配符 CPP版本

51 阅读1分钟

描述

  1. 能被*和?匹配的字符仅由英文字母和数字0到9组成
  2. 匹配时不区分大小写

解析

DP能过

#include <iostream>
#include <vector>
#include <string>
using namespace std;
bool isvaild(char e) {
	return isalpha(e) || isdigit(e);
}
int main() {
	string p,s;
	cin >> p >> s;
	int pn = p.size();
	int sn = s.size();
	vector<vector<int>> dp(sn+1,vector<int>(pn+1,0));
	dp[0][0] = 1;
	for (int i = 1; i <= pn; ++i) {
		if (p[i-1] == '*') {
			dp[0][i] = 1;
		} else {
			break;
		}
	}
	for (int i = 1; i <= sn; ++i) {
		for (int j = 1; j <= pn; ++j) {
			if (p[j-1] == '*') {
                                //用到*再检查
				dp[i][j] = (dp[i-1][j]&&isvaild(s[i-1])) | (dp[i][j-1]); 
                                
			} else if ((p[j-1] == '?' && isvaild(s[i-1])) 
			||tolower(p[j-1]) == tolower(s[i-1])) {
				dp[i][j] = dp[i-1][j-1];
			}
		}
	}
	if(dp[sn][pn]) {
		cout << "true";
	} else {
		cout << "false";
	}
	return 0;
}
// 64 位输出请用 printf("%lld")

递归会超时

#include <cctype>
#include <iostream>
using namespace std;
bool isvaild(char c) {
    return isdigit(c) || isalpha(c);
}
bool helper(const string& s1, const string& s2, string::size_type p1, string::size_type p2) {
    if (p1 == s1.size() && p2 == s2.size()) return true;
    if (p1 == s1.size() || p2 == s2.size()) return false;

    if (s1[p1] == s2[p2] || toupper(s1[p1]) == toupper(s2[p2])) {
        return helper(s1,s2,p1+1,p2+1);
    } else if (s1[p1] == '?' && isvaild(s2[p2])) {
        return helper(s1,s2,p1+1,p2+1);
    } else if (s1[p1] == '*' && isvaild(s2[p2])) {
        return helper(s1, s2,p1,p2+1) ||
        helper(s1, s2, p1 + 1, p2 + 1) ||
        helper(s1, s2, p1 + 1, p2); 
    }
    return false;
}
int main() {
    string s1;
    string s2;
    cin >> s1;
    cin >> s2;
    if (helper(s1,s2,0,0)) {
        cout << "true";
        return 0;
    }
    cout << "false";
}
// 64 位输出请用 printf("%lld")

递归写出满足题目两个要求的代码并不难。

DP时需要小心p为*的情况,取dp[i-1][j]时意味着匹配1个或多个s[i-1],这时需要额外检查isvaild(s[i-1])