【WildCard Matching】cpp
题目:
Implement wildcard pattern matching with support for '?' and '*'.
'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence). The matching should cover the entire input string (not partial). The function prototype should be:
bool isMatch(const char *s, const char *p) Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false
代码:
class Solution {
public:
    bool isMatch(string s, string p) {
        const size_t len_s = s.length();
        const size_t len_p = p.length();
        if ( len_s>= ) return false; // escape the last extreme large test case
        bool dp[len_s+][len_p+];
        // dp initialization
        dp[][] = true;
        for ( size_t i = ; i <=len_s; ++i ) dp[i][]=false;
        for ( size_t i = ; i <=len_p; ++i ) dp[][i] = p[i-]=='*' && dp[][i-];
        // dp process
        for ( size_t i = ; i <=len_s; ++i ){
            for ( size_t j = ; j <=len_p; ++j ){
                if ( p[j-]!='*'){
                    dp[i][j] = dp[i-][j-] && ( p[j-]==s[i-] || p[j-]=='?' );
                }
                else{
                    dp[i][j] = dp[i-][j] || dp[i-][j-] || dp[i][j-];
                }
            }
        }
        return dp[len_s][len_p];
    }
};
tips:
采用动态规划的思路,模仿Regular Expression Matching这道题的思路。
判断p的下一个元素是不是‘*’,分两种情况讨论。
这里需要注意的是如果p的下一个元素是‘*’,则需要讨论从不同之前状态转移到dp[i][j]的几种case。这道题由于放宽了对*的限制,所以判断的情况比较直观了:dp[i-1][j] dp[i-1][j-1] dp[i][j-1]只要有一个成立dp[i][j]就为真了。
但是第1801个test case是超大集合,s超过30000个字符,所以直接跳过了。
这道题其实可以尝试一下Greedy算法,兴许就不用作弊,而且空间复杂度降低了。
==============================================
无力再去想Greedy算法了,直接参考一个 extremely elegant的c++ code
这是原创blog:http://yucoding.blogspot.sg/2013/02/leetcode-question-123-wildcard-matching.html
上面原创的blog在leetcode的discuss上被解读了一遍:https://leetcode.com/discuss/10133/linear-runtime-and-constant-space-solution
参照上面两个blog,按照leetcode上新版的接口,写的代码如下:
class Solution {
public:
    bool isMatch(string s, string p) {
        const size_t len_s = s.length();
        const size_t len_p = p.length();
        size_t index_s = ;
        size_t index_p = ;
        size_t index_star = INT_MIN;
        size_t index_match_by_star = ;
        while ( index_s < len_s )
        {
            if ( (index_p<len_p && p[index_p]=='?') || p[index_p]==s[index_s] )
            {
                ++index_s;
                ++index_p;
                continue;
            }
            if ( index_p<len_p && p[index_p]=='*' )
            {
                index_star = index_p;
                ++index_p;
                index_match_by_star = index_s;
                continue;
            }
            if ( index_star!=INT_MIN )
            {
                index_p = index_star + ;
                index_s = index_match_by_star + ;
                ++index_match_by_star;
                continue;
            }
            return false;
        }
        while ( index_p<len_p && p[index_p]=='*' ) ++index_p;
        return index_p==len_p;
    }
};
思路和代码逻辑完全按照blog里面大神的逻辑,大神的思路巧妙,代码consice,只能膜拜并模仿了。
这里面要有一个地方注意一下:由于接口参数由char *改为了string,因此最后一个'\0'就没有了。
所以,不能直接使用p[index_p],每次使用p[index_p]之前,需要判断index_p<len_p这个条件,这样就可以不用跳过最后一组数据并且AC了。
正则匹配这个告一段落,个人感觉还是dp的思路通用性好一些:如果能列出来状态转移的表达式,就可以不断尝试转移的case,最终使得代码AC。
=============================================================
第二次过这道题,直接照着之前的dp代码弄的。思路就记住就好了。
class Solution {
public:
    bool isMatch(string s, string p) {
            if ( s.size()>= ) return false;
            bool dp[s.size()+][p.size()+];
            std::fill_n(&dp[][], (s.size()+)*(p.size()+), false);
            dp[][] = true;
            for ( int j=; j<=p.size(); ++j )
            {
                dp[][j] = dp[][j-] && p[j-]=='*';
            }
            for ( int i=; i<=s.size(); ++i )
            {
                for ( int j=; j<=p.size(); ++j )
                {
                    if (p[j-]!='*')
                    {
                        dp[i][j] = dp[i-][j-] && ( s[i-]==p[j-] || p[j-]=='?' );
                    }
                    else
                    {
                        dp[i][j] = dp[i-][j-] || dp[i-][j] || dp[i][j-];
                    }
                }
            }
            return dp[s.size()][p.size()];
    }
};
【WildCard Matching】cpp的更多相关文章
- 【 Regular Expression Matching 】cpp
		
题目: Implement regular expression matching with support for '.' and '*'. '.' Matches any single chara ...
 - hdu 4739【位运算】.cpp
		
题意: 给出n个地雷所在位置,正好能够组成正方形的地雷就可以拿走..为了简化题目,只考虑平行于横轴的正方形.. 问最多可以拿走多少个正方形.. 思路: 先找出可以组成正方形的地雷组合cnt个.. 然后 ...
 - Hdu 4734 【数位DP】.cpp
		
题意: 我们定义十进制数x的权值为f(x) = a(n)*2^(n-1)+a(n-1)*2(n-2)+...a(2)*2+a(1)*1,a(i)表示十进制数x中第i位的数字. 题目给出a,b,求出0~ ...
 - 【Valid Sudoku】cpp
		
题目: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could ...
 - 【Permutations II】cpp
		
题目: Given a collection of numbers that might contain duplicates, return all possible unique permutat ...
 - 【Subsets II】cpp
		
题目: Given a collection of integers that might contain duplicates, nums, return all possible subsets. ...
 - 【Sort Colors】cpp
		
题目: Given an array with n objects colored red, white or blue, sort them so that objects of the same ...
 - 【Sort List】cpp
		
题目: Sort a linked list in O(n log n) time using constant space complexity. 代码: /** * Definition for ...
 - 【Path Sum】cpp
		
题目: Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up ...
 
随机推荐
- 举例详解CSS中的的优先级
			
计算优先级 优先级是根据由每种选择器类型构成的级联字串计算而成的.他是一个对应匹配表达式的权重. 如果优先级相同,靠后的 CSS 会应用到元素上. 注意:元素在文档树中的位置是不会影响优先级的优先级顺 ...
 - 微信Api
			
//定义变量 HttpRequest Request; HttpResponse Response; HttpServerUtility Server; HttpContext Context; pr ...
 - Python在金融,数据分析,和人工智能中的应用
			
Python在金融,数据分析,和人工智能中的应用 Python最近取得这样的成功,而且未来似乎还会继续下去,这有许多原因.其中包括它的语法.Python开发人员可用的科学生态系统和数据分析库.易于 ...
 - WordPress 非插件实现拦截无中文留言
			
Some Chinese Please 插件可以拦截不带中文字的留言,之前本博客一直在用效果不错,不写入数据库,可有效地减少 spam 对服务器的无谓使用,其实可以将插件简化一下,直接用代码实现.将下 ...
 - Thinkphp 获取当前url
			
$_GET['_URL_'] 获取整个url,返回值是数组 $Think.MODULE_NAME 获取当前class的名称 $Think.ACTION_NAME 获取当前action的方法名称
 - 直接拿来用!超实用的Java数组技巧攻略[转]
			
来自csdn http://www.csdn.net/article/2013-09-16/2816947-methods-for-java-arrays 本文分享了关于Java数组最顶级的11大方法 ...
 - 删:[CentOS 7] 安装nginx
			
下载对应当前系统版本的nginx包(package) # wget http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-cent ...
 - delphi常用函数过程
			
数据类型转化 1.1. 数值和字符串转化 Procedure Str(X [: Width [ : Decimals ]]; var S); 将数值X按照一定格式转化成字符串S.Wid ...
 - 一元三次方程 (codevs 1038)题解
			
[问题描述] 有形如:ax3+bx2+cx+d=0这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差 ...
 - Python学习教程(learning Python)--1.3 Python数据输入
			
多数应用程序都有数据输入语句,用于读入数据,和用户进行交互,在Python语言里,可以通过raw_input函数实现数据的从键盘读入数据操作. 基本语法结构:raw_input(prompt) 通常p ...