【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 ...
随机推荐
- C puzzles详解【51-57题】
第五十一题 Write a C function which does the addition of two integers without using the '+' operator. You ...
- sqlserver同步表的脚本
/* --同步读者 insert into [172.21.200.8].gdlisxp.dbo.读者库(借书证号,读者条码,姓名,性别,身份证号, 读者级别,级别代码,单位代码,单位,可外借,发证日 ...
- MessageBox详解
MessageBox.Show();可谓是winform开发中用的次数最多的东东啦.先贴一张msdn的图解 msdn好像没有更新哎,只提供了这几种方法,并且参数名称和最新的有差别,但实际上messag ...
- Bootstrap Alert Auto Close
http://stackoverflow.com/questions/23101966/bootstrap-alert-auto-close http://jsfiddle.net/mfX57/ $( ...
- 多屏判断css改写
function replaceBodyClass(){ for(var i in map){ if(map[i](width)){ document.body.className = documen ...
- 学习c语言的第9天
#include <stdio.h> int main() { float sum=0,wage=0; int i=1; int num; printf("+++平均工资统计程序 ...
- Android Material Design:NavigationView抽屉导航菜单
需要添加的包: 测试代码: package com.zzw.navigationview; import android.app.Activity; import android.os.Bundle; ...
- ContactsContract.CommonDataKinds【Translated By KillerLegend】
http://developer.android.com/reference/android/provider/ContactsContract.CommonDataKinds.html interf ...
- Laravel 5 基础(十一)- 表单验证
在建立一个文章的时候,如果你什么都不输入直接提交,ok,你获得了一个空的文章,没有任何错误提示,这是不对的.在命令行下运行 php artisan 可以看到一个选项 make:request,新建一个 ...
- 【转】Doscommand-操作Cmd的第三方控件
核心用法: Doscommand1.CommandLine := 'cmd /c' +[命令];Doscommand1.OutputLines :=Memo1.Lines;Doscommand1.Ex ...