/*
https://leetcode.cn/problems/regular-expression-matching/?favorite=2cktkvj
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。
'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
示例 1:
输入:s = "aa", p = "a"
输出:false
解释:"a" 无法匹配 "aa" 整个字符串。
示例 2:
输入:s = "aa", p = "a*"
输出:true
解释:因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
示例 3:
输入:s = "ab", p = ".*"
输出:true
解释:".*" 表示可匹配零个或多个('*')任意字符('.')。
提示:
1 <= s.length <= 20
1 <= p.length <= 30
s 只包含从 a-z 的小写字母。
p 只包含从 a-z 的小写字母,以及字符 . 和 *。
保证每次出现字符 * 时,前面都匹配到有效的字符
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/regular-expression-matching
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
// 思路:开始用了s,p往前递进,逐步判断的方式,总有测试case无法正确处理,看了CSDN上用动态规划的方法,重新实现了
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#define MAX_P_LEN 32
#define MAX_IN_LEN 24
enum MATCH_MODE {
ANY_ONE = 1, // .
ANY_MORE = 2, // .*
FIXED_ONE = 4, // a
FIXED_MORE = 8, // a*
};
struct regular_exp {
char expr;
enum MATCH_MODE mode;
};
//static bool matched_arr[MAX_P_LEN][MAX_IN_LEN] = {false};
//static struct regular_exp expr_arr[MAX_P_LEN];
#define MATCH_ONE '.'
#define MATCH_PRE '*'
static int parse_regular_exp(const char *expr, struct regular_exp *expr_arr)
{
const char *p = expr;
int size = 1;
while ((*p != '\0') && (size < MAX_P_LEN)) {
expr_arr[size].expr = *p;
if (*(p + 1) == MATCH_PRE) {
if (*p == MATCH_ONE) {
expr_arr[size].mode = ANY_MORE;
} else {
expr_arr[size].mode = FIXED_MORE;
}
p++;
} else if (*p == MATCH_ONE) {
expr_arr[size].mode = ANY_ONE;
} else {
expr_arr[size].mode = FIXED_ONE;
}
size++;
p++;
}
return size;
}
static bool do_match(int row, int col, char in_char, struct regular_exp *expr_arr, bool matched_arr[][MAX_IN_LEN])
{
bool ret = false;
switch (expr_arr[row].mode) {
case ANY_ONE:
case FIXED_ONE:
if ((expr_arr[row].mode == FIXED_ONE) && (in_char != expr_arr[row].expr)) {
break;
}
//handle char match case
ret = matched_arr[row - 1][col - 1];
break;
case ANY_MORE:
case FIXED_MORE:
if ((in_char == expr_arr[row].expr) || (expr_arr[row].mode == ANY_MORE)) { //match the char
ret = matched_arr[row - 1][col - 1] || matched_arr[row][col - 1] || matched_arr[row - 1][col];
} else { //not match the char, could ignore
ret = matched_arr[row - 1][col];
}
break;
default:
break;
}
return ret;
}
bool isMatch(const char *s, const char *p)
{
//just for leetcode, not need malloc for small memory
bool matched_arr[MAX_P_LEN][MAX_IN_LEN] = {false};
struct regular_exp expr_arr[MAX_P_LEN];
int in_size = strlen(s) + 1; // 0 as assisted data
int expr_size = parse_regular_exp(p, expr_arr); // index 0 as assisted data
int i = 0, j = 0;
assert(in_size < MAX_IN_LEN);
assert(strlen(p) < MAX_P_LEN);
memset(matched_arr, sizeof(matched_arr), 0);
//row 0 and col0 as assist data, set its char as 0 and regular exp as 0:
matched_arr[0][0] = true;
for (i = 1; i < expr_size; i++) {
if (expr_arr[i].mode & (ANY_MORE | FIXED_MORE)) {
matched_arr[i][0] = matched_arr[i - 1][0];
}
}
for (i = 1; i < expr_size; i++) {
for (j = 1; j < in_size; j++) {
matched_arr[i][j] = do_match(i, j, s[j - 1], expr_arr, matched_arr);
}
}
return matched_arr[i-1][j-1];
}
#define IN_SIZE 256
static char in_str[IN_SIZE];
static char reg_exp[IN_SIZE];
int main(int argc, char *argv[])
{
printf("please input two strings: in-string & reg-expr\n");
scanf("%s %s", in_str, reg_exp);
printf("check match in: %s, exp: %s\n", in_str, reg_exp);
printf("matched: %s\n", isMatch(in_str, reg_exp) ? "true" : "false");
return 0;
}
支持 ‘.‘ 和 ‘*‘ 的正则表达式匹配
最新推荐文章于 2023-07-27 10:13:25 发布