首页 > 试题广场 >

字符串匹配问题

[编程题]字符串匹配问题
  • 热度指数:2503 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
对于字符串str,其中绝对不含有字符’.’和‘*’再给定字符串exp,其中可以含有’.’或’‘*’,’*’字符不能是exp的首字符,并且任意两个’*‘字符不相邻。exp中的’.’代表任何一个字符,exp中的’*’表示’*‘的前一个字符可以有0个或者多个。请写一个函数,判断str是否能被exp匹配(注意:输入的数据不保证合法,但只含小写字母和‘.’和‘*’)。

输入描述:
输入包含两行,两个字符串,分别代表str和exp


输出描述:
如果str是能被exp匹配,请输出“YES”,否则输出“NO”。
示例1

输入

abc
abc

输出

YES
示例2

输入

abcd
.*

输出

YES

备注:
时间复杂度,额外空间复杂度,(n为字符串str长度,m为字符串exp长度)
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>

// 初始化一个动态大小的矩阵
#define INIT_MATRIX(TYPE, PTR, COL, ROW) \
    (PTR) = (TYPE **) malloc(sizeof(TYPE *) * (COL));\
    for (int i = 0; i < (COL); i++)\
        (PTR)[i] = (TYPE *) calloc((ROW), sizeof(TYPE))

// 释放一个动态大小的矩阵
#define FREE_MATRIX(PTR, COL) \
    for (int i = 0; i < (COL); i++) {\
        free((PTR)[i]);\
    }\
    free((PTR))
#define MAXLEN 301

bool is_valid(char *str, char *exp);

bool **get_dp(const char *str, const char *exp, int str_len, int exp_len);

int main(void) {
    char str[MAXLEN], exp[MAXLEN];
    scanf("%s%s", str, exp);
    if (!is_valid(str, exp)) {
        printf("NO\n");
        return 0;
    }
    int str_len = (int) strlen(str);
    int exp_len = (int) strlen(exp);
    bool **dp = get_dp(str, exp, str_len, exp_len);
    for (int i = str_len - 1; i >= 0; i--) {
        for (int j = exp_len - 2; j >= 0; j--) {
            if (exp[j + 1] != '*') {
                dp[i][j] = (exp[j] == '.' || str[i] == exp[j])
                           && dp[i + 1][j + 1];
            } else {
                int si = i;
                while (si != str_len && (exp[j] == '.' || str[si] == exp[j])) {
                    if (dp[si][j + 2]) {
                        dp[i][j] = true;
                        break;
                    }
                    si++;
                }
                if (!dp[i][j]) {
                    dp[i][j] = dp[si][j + 2];
                }
            }
        }
    }
    printf("%s\n", dp[0][0] ? "YES" : "NO");
    FREE_MATRIX(dp, strlen(str));
    return 0;
}

bool is_valid(char *str, char *exp) {
    for (int i = 0; i < strlen(str); i++) {
        if (str[i] == '.' || str[i] == '*') {
            return false;
        }
    }
    for (int i = 0; i < strlen(exp); i++) {
        if (str[i] == '*' && (i == 0 || str[i - 1] == '*')) {
            return false;
        }
    }
    return true;
}

bool **get_dp(const char *str, const char *exp, int str_len, int exp_len) {
    bool **dp;
    INIT_MATRIX(bool, dp, str_len + 1, exp_len + 1);
    dp[str_len][exp_len] = true;
    for (int j = exp_len - 2; j >= 0; j -= 2) {
        dp[str_len][j] = exp[j + 1] == '*';
        if (!dp[str_len][j]) {
            break;
        }
    }
    dp[str_len - 1][exp_len - 1] = exp[exp_len - 1] == '.' ||
                                   str[str_len - 1] == exp[exp_len - 1];
    return dp;
}

发表于 2022-02-12 14:24:46 回复(0)