题目:

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的更多相关文章

  1. 【 Regular Expression Matching 】cpp

    题目: Implement regular expression matching with support for '.' and '*'. '.' Matches any single chara ...

  2. hdu 4739【位运算】.cpp

    题意: 给出n个地雷所在位置,正好能够组成正方形的地雷就可以拿走..为了简化题目,只考虑平行于横轴的正方形.. 问最多可以拿走多少个正方形.. 思路: 先找出可以组成正方形的地雷组合cnt个.. 然后 ...

  3. 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~ ...

  4. 【Valid Sudoku】cpp

    题目: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could ...

  5. 【Permutations II】cpp

    题目: Given a collection of numbers that might contain duplicates, return all possible unique permutat ...

  6. 【Subsets II】cpp

    题目: Given a collection of integers that might contain duplicates, nums, return all possible subsets. ...

  7. 【Sort Colors】cpp

    题目: Given an array with n objects colored red, white or blue, sort them so that objects of the same ...

  8. 【Sort List】cpp

    题目: Sort a linked list in O(n log n) time using constant space complexity. 代码: /** * Definition for ...

  9. 【Path Sum】cpp

    题目: Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up ...

随机推荐

  1. JqueryMobile动态生成listView并实现刷新的两种方法

    本篇文章主要是对JqueryMobile动态生成listView并实现刷新的两种方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助 JqueryMobile动态生成listView并实现刷新 ...

  2. 两张table数据同步--使用触发器

    数据同步, 如果每天同步一次的话可以使用SSIS,跑JOB等,可以同步不同的DB的数据: 实时的可以使用触发器,在同一个DB中(或者DB Link): USE [test] GO IF EXISTS( ...

  3. Silverlight 独立存储(IsolatedStorageFile)

    1.在Web中添加天气服务引用地址 http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl 2.在Web中添加Wcf服务接口I ...

  4. 一、MongoDB的下载、安装与部署

    1.什么是MongoDB? 它是介于关系型数据库和非关系型数据库之间的一种NoSQL数据库,用C++编写,是一款集敏捷性.可伸缩性.扩展性于一身的高性能的面向文档的通用数据库. 2.为什么要用Mong ...

  5. MySQL的相关概念介绍

    MySQL 为关系型数据库(Relational Database Management System), 这种所谓的"关系型"可以理解为"表格"的概念, 一个 ...

  6. BM串匹配算法

    串匹配算法最常用的情形是从一篇文档中查找指定文本.需要查找的文本叫做模式串,需要从中查找模式串的串暂且叫做查找串吧. BM算法好后缀规则 公式: 对于长度为m的模式串P,在i处失配时,模式串向前滑动的 ...

  7. redis 入门

    1.命令行工具 在windows上巧命令行指令,实在是令人痛苦,本人实在是受不了windows下cmd的笨,powershell的蠢,只能换一个了. 介绍一款cmd工具cmder(github上开源) ...

  8. 学习jQuery在表单信息修改之中的常用方法;

    submitHandler: function (form) { var parm = $("#myform").serialize(); var url = $("#m ...

  9. Decorator模式

    Decorator模式能够像标准的继承一样为类添加新的功能. 不同于标准继承机制的是,如果对象进行了实例化,Decorator模式能够在运行时动态地为对象添加新的功能. <?php abstra ...

  10. 【PHP开源产品】Ecshop的商品筛选功能实现分析之一

    一.首先,说明一下为什么要对category.php文件进行分析. 原因如下: ①个人对商城类商品筛选功能的实现比较好奇: ②对商城中关于商品的数据表设计比较感兴趣.(该功能涉及到与数据库的交互,而且 ...