Leetcode-10正则表达式匹配

这个C语言版本花了一点时间,主要因为两个方面:

1. 变量定义数组的长度,需要事先申请内存

2. 题目本身的逻辑,看了个Java改编的C版本,好像Java版本本来也有点问题。

/*
1, If p.charAt(j) == s.charAt(i) :  dp[i][j] = dp[i-1][j-1];
2, If p.charAt(j) == '.' : dp[i][j] = dp[i-1][j-1];
3, If p.charAt(j) == '*': 
   here are two sub conditions:
               1   if p.charAt(j-1) != s.charAt(i) : dp[i][j] = dp[i][j-2]  //in this case, a* only counts as empty
               2   if p.charAt(i-1) == s.charAt(i) or p.charAt(i-1) == '.':
                              dp[i][j] = dp[i-1][j]    //in this case, a* counts as multiple a 
                           or dp[i][j] = dp[i][j-1]   // in this case, a* counts as single a
                           or dp[i][j] = dp[i][j-2]   // in this case, a* counts as empty
*/



bool isMatch(char* s, char* p) {
    if(!s||!p) return false;
    int sLen = strlen(s);
    int pLen = strlen(p);
    int **dp;
    dp = (int **)malloc(sizeof(int *) * (sLen+1));//分配指针数组
    for(int i=0; i<sLen+1; i++)
    {
           dp[i] = (int *)malloc(sizeof(int) * (pLen+1));//分配每个指针所指向的数组
}

    dp[0][0] = 1;
    for (int i = 0; i< pLen; i++)
    {
        if(p[i]=='*'&& dp[0][i-1])
        {
            dp[0][i+1] = 1;//默认第一个字符不会是*,所以不会越界

        }
    }
    for(int j=0; j<sLen ; j++)
    {
        for(int k=0; k<pLen; k++) {
            if (p[k] == '.') {
                dp[j + 1][k + 1] = dp[j][k];
            }
            else if (p[k] == s[j]) {
                dp[j + 1][k + 1] = dp[j][k];
        }
            else if (p[k] == '*') {
                //if (p[k - 1] != s[j] && p[k - 1] != '.') {
                 //   dp[j + 1][k + 1] = dp[j + 1][k - 1];
                //} else {
               //     dp[j + 1][k + 1] = (dp[j + 1][k] || dp[j][k + 1] || dp[j + 1][k - 1]);
               // }
                dp[j+1][k+1] = dp[j+1][k-1] || dp[j+1][k] || (dp[j][k+1] && (s[j]==p[k-1] || p[k-1]=='.'));
            }

        }
    }
    return dp[sLen][pLen]==1?true:false;
}

C++版本

class Solution {
public:
    bool isMatch(string s, string p) {
        int m = s.size(), n = p.size();
        vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));
        dp[0][0] = true;
        for (int i = 0; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (j > 1 && p[j - 1] == '*') {
                    dp[i][j] = dp[i][j - 2] || (i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == '.') && dp[i - 1][j]);
                } else {
                    dp[i][j] = i > 0 && dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
                }
            }
        }
        return dp[m][n];
    }
};

这里给出的都是动态规划法写的版本。

给大家看一个C语言4ms的范例,LeetCode有一点就是,你提交通过了才能看到别人更好的代码。

typedef struct{
    char p;
    char s;
}data;

bool isMatch(char* s, char* p) {
    int lp = strlen(p), ls = strlen(s), e = 0, i, j;
    data *cp = malloc(sizeof(data) * lp);
    for (i = 0; i < lp; ++i){
        if (p[i] == '*'){
            cp[e-1].s = 1;
        }else{
            cp[e].p = p[i];
            cp[e].s = 0;
            e++;
        }
    }
    int *dp = malloc(sizeof(int) * (ls + 1) * (e + 1));
    memset(dp, 0, sizeof(int) * (ls + 1) * (e + 1));
    dp[0] = 1;
    for (i = 0; i < ls; ++i){
        for (j = 0; j < e; ++j){
            if (dp[i * (e+1) + j]){
                if (cp[j].p == '.'){
                    if (cp[j].s == 0){
                        dp[(i+1) * (e+1) + (j+1)] = 1;
                    }else{
                        int k;
                        for (k = i; k <= ls; ++k){
                            dp[k * (e+1) + (j+1)] = 1;
                        }
                    }
                }else{
                    if (cp[j].s == 0){
                        if (cp[j].p == s[i]){
                            dp[(i+1) * (e+1) + (j+1)] = 1;
                        }
                    }else{
                        int k;
                        dp[i * (e+1) + (j+1)] = 1;
                        for (k = i; cp[j].p == s[k] && k < ls; ++k){
                            dp[(k+1) * (e+1) + (j+1)] = 1;
                        }
                    }
                }
            }
        }
    }
    for (j = 0; j < e; ++j){
        if (dp[ls * (e+1) + j] && cp[j].s == 1){
            dp[ls * (e+1) + (j+1)] = 1;
        }
    }
    int res = dp[ls * (e+1) + e];
    free(dp);
    free(cp);
    return res;
}

再来一个8ms的,主要看看这个二维数组的定义,竟然可以直接定义。。。。

bool isMatch(char* s, char* p) {
    int m = strlen(s);
	int n = strlen(p);
    
    int i,j;

	bool dp[m+1][n+1];

	dp[0][0] = true;
	
	for ( i = 1; i <= m; i++) 
		dp[i][0] = false; 
	
	for (j = 1; j <= n; j++) 
		dp[0][j] = j > 1 && '*' == p[j - 1] && dp[0][j - 2];


	for(i = 1;i <= m;i++)
	{
		for(j = 1;j <= n;j++)
		{
			if(p[j-1] == '*')
				dp[i][j] = dp[i][j-2] || (s[i-1] == p[j-2] || p[j-2] == '.') && dp[i-1][j];
			else 
			
				dp[i][j] = (p[j-1] == '.' || s[i-1] == p[j-1]) && dp[i-1][j-1];
		}
	}

	return dp[m][n];
    
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值