<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Programming Life with Music &#187; 面试题</title>
	<atom:link href="http://jackaldire.com/tag/%e9%9d%a2%e8%af%95%e9%a2%98/feed/" rel="self" type="application/rss+xml" />
	<link>http://jackaldire.com</link>
	<description>JackalDire &#039;s Blog</description>
	<lastBuildDate>Tue, 13 Jul 2010 08:29:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>[一道面试题]含有*的字符串匹配问题</title>
		<link>http://jackaldire.com/200911/string-matching-with-wildcard/</link>
		<comments>http://jackaldire.com/200911/string-matching-with-wildcard/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 01:13:43 +0000</pubDate>
		<dc:creator>JackalDire</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[算法]]></category>
		<category><![CDATA[面试题]]></category>

		<guid isPermaLink="false">http://jackaldire.com/?p=76</guid>
		<description><![CDATA[Question 字符串1：只含有英文字母 字符串2：含有英文字母和*，其中符号*表示匹配任意字符0或者多次，即正则表达式里面的含义。 现在给定这样的两个串，要求判断是否匹配？ bool isMatch ( const char *str1, const char *str2) 例如：str1 = &#8220;hello&#8221;, str2 = &#8220;he*o&#8221;，则二者匹配，返回true,str1 = &#8220;hello&#8221;, str2 = &#8220;he*l&#8221;，则不匹配，返回false。 Solution 关键是如何处理*，首先想到的就是回溯，在纸上画了一下得到如下算法 设输入是两个字符串 s, t, 其中t可能包含* 1.当*t不是*的时候, 就像普通的串匹配一样, 移动s和t 2.当*t是*的时候, 假设*t后面第一个不是*的字符是x, 若x是null, 直接匹配成功, 否则在s中找到当前位置后所有字符x的位置, 这时候问题转化成了t中x后的串和s中当前位置以后所有以x为开始的串的匹配问题, 递归调用即可, 其中任意一个匹配成功, 则原串匹配成功, 若都没有匹配成功则匹配失败. 3.当*s和*t其中一个是null时 跳出循环, 若此时 *t == &#8216;*&#8217;, 则++t 知道 t != &#8216;*&#8217;, 这时若 [...]]]></description>
			<content:encoded><![CDATA[<h2>Question</h2>
<p>字符串1：只含有英文字母<br />
字符串2：含有英文字母和*，其中符号*表示匹配任意字符0或者多次，即正则表达式里面的含义。</p>
<p>现在给定这样的两个串，要求判断是否匹配？<br />
bool isMatch ( const char *str1, const char *str2)</p>
<p>例如：str1 = &#8220;hello&#8221;, str2 = &#8220;he*o&#8221;，则二者匹配，返回true,str1 = &#8220;hello&#8221;, str2 = &#8220;he*l&#8221;，则不匹配，返回false。</p>
<p><span id="more-76"></span></p>
<h2>Solution</h2>
<p>关键是如何处理*，首先想到的就是回溯，在纸上画了一下得到如下算法</p>
<p>设输入是两个字符串 s, t, 其中t可能包含* <.p><br />
1.当*t不是*的时候, 就像普通的串匹配一样, 移动s和t <br />
2.当*t是*的时候,  假设*t后面第一个不是*的字符是x,  若x是null, 直接匹配成功,  否则在s中找到当前位置后所有字符x的位置, 这时候问题转化成了t中x后的串和s中当前位置以后所有以x为开始的串的匹配问题, 递归调用即可, 其中任意一个匹配成功, 则原串匹配成功, 若都没有匹配成功则匹配失败.</p>
<p>3.当*s和*t其中一个是null时 跳出循环, 若此时 *t  == &#8216;*&#8217;, 则++t 知道 t != &#8216;*&#8217;,  这时若 *t == 0 则代表匹配成功, 否则匹配失败。</p>
<p>代码如下:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;cstring&gt;</span>
<span style="color: #339900;">#include &lt;iostream&gt;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">bool</span> is_match<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> s, <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> t<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>s <span style="color: #000040;">&amp;&amp;</span> <span style="color: #000040;">*</span>t<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>t <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #FF0000;">'*'</span> <span style="color: #000040;">&amp;&amp;</span> <span style="color: #000040;">*</span>s <span style="color: #000080;">==</span> <span style="color: #000040;">*</span>t<span style="color: #008000;">&#41;</span>
            <span style="color: #000040;">++</span>s, <span style="color: #000040;">++</span>t<span style="color: #008080;">;</span>
        <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>t <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #FF0000;">'*'</span> <span style="color: #000040;">&amp;&amp;</span> <span style="color: #000040;">*</span>s <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #000040;">*</span>t<span style="color: #008000;">&#41;</span>
            <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>t <span style="color: #000080;">==</span> <span style="color: #FF0000;">'*'</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #0000ff;">do</span> <span style="color: #000040;">++</span>t<span style="color: #008080;">;</span> <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>t <span style="color: #000080;">==</span> <span style="color: #FF0000;">'*'</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
            <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>t <span style="color: #000080;">==</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
            <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span> <span style="color: #008080;">;</span> <span style="color: #000040;">*</span>s<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>s<span style="color: #008000;">&#41;</span>
                <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>s <span style="color: #000080;">==</span> <span style="color: #000040;">*</span>t <span style="color: #000040;">&amp;&amp;</span> is_match<span style="color: #008000;">&#40;</span>s<span style="color: #000040;">+</span><span style="color: #0000dd;">1</span>, t<span style="color: #000040;">+</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
                    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
            <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>t <span style="color: #000080;">==</span> <span style="color: #FF0000;">'*'</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">++</span>t<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>s <span style="color: #000080;">==</span> <span style="color: #000040;">*</span>t<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> argv<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>is_match<span style="color: #008000;">&#40;</span>argv<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span>, argv<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;match&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">else</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;not match&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<h2>改进</h2>
<p>上面的暴力算法如果遇到“aaaaaaaaaaaaaaaa”，“a*a*a*a*a*a*a*a*a*a*a*a”这样的输入，会达到2^n的复杂度，是无法接受的。注意到，递归搜索是有很多重复的状态，自然就想到了记忆化搜索，时间空间复杂度均为O(n^2)，代码如下：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;cstring&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #0000ff;">const</span> <span style="color: #0000ff;">int</span> MAX_LEN <span style="color: #000080;">=</span> <span style="color: #0000dd;">1024</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">int</span> dp<span style="color: #008000;">&#91;</span>MAX_LEN<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#91;</span>MAX_LEN<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">bool</span> is_match<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> p, <span style="color: #0000ff;">int</span> q, <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> s, <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> t<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>dp<span style="color: #008000;">&#91;</span>p<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span> <span style="color: #000080;">&gt;=</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">return</span> dp<span style="color: #008000;">&#91;</span>p<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">int</span> <span style="color: #000040;">&amp;</span>ans <span style="color: #000080;">=</span> dp<span style="color: #008000;">&#91;</span>p<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>s<span style="color: #008000;">&#91;</span>p<span style="color: #008000;">&#93;</span> <span style="color: #000040;">&amp;&amp;</span> <span style="color: #000040;">!</span>t<span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        ans <span style="color: #000080;">=</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>s<span style="color: #008000;">&#91;</span>p<span style="color: #008000;">&#93;</span> <span style="color: #000040;">||</span> <span style="color: #000040;">!</span>t<span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>t<span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span> <span style="color: #000080;">==</span> <span style="color: #FF0000;">'*'</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            ans <span style="color: #000080;">=</span> is_match<span style="color: #008000;">&#40;</span>p, q <span style="color: #000040;">+</span> <span style="color: #0000dd;">1</span>, s, t<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>t<span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span> <span style="color: #000080;">==</span> <span style="color: #FF0000;">'*'</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            ans <span style="color: #000080;">=</span> is_match<span style="color: #008000;">&#40;</span>p <span style="color: #000040;">+</span> <span style="color: #0000dd;">1</span>, q, s, t<span style="color: #008000;">&#41;</span>
                <span style="color: #000040;">||</span> is_match<span style="color: #008000;">&#40;</span>p, q <span style="color: #000040;">+</span> <span style="color: #0000dd;">1</span>, s, t<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>s<span style="color: #008000;">&#91;</span>p<span style="color: #008000;">&#93;</span> <span style="color: #000080;">==</span> t<span style="color: #008000;">&#91;</span>q<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            ans <span style="color: #000080;">=</span> is_match<span style="color: #008000;">&#40;</span>p <span style="color: #000040;">+</span> <span style="color: #0000dd;">1</span>, q <span style="color: #000040;">+</span> <span style="color: #0000dd;">1</span>, s, t<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">return</span> ans<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">bool</span> is_match<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> s, <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> t<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000dd;">memset</span><span style="color: #008000;">&#40;</span>dp, <span style="color: #000040;">-</span><span style="color: #0000dd;">1</span>, <span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span>dp<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> is_match<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span>, <span style="color: #0000dd;">0</span>, s, t<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>  
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> argv<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>is_match<span style="color: #008000;">&#40;</span>argv<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span>, argv<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;match&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">else</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;not match&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>


	<h4>Related Post</h4>
	<ul class="st-related-posts">
	<li><a href="http://jackaldire.com/200908/quick-sort-analysis/" title="快速排序详细分析 (2009年08月27日)">快速排序详细分析</a> (4)</li>
	<li><a href="http://jackaldire.com/200908/reverse-token/" title="[备忘]倒置字符串中的单词 (2009年08月18日)">[备忘]倒置字符串中的单词</a> (0)</li>
	<li><a href="http://jackaldire.com/200905/smart-way-to-solve-fibonacci/" title="Fibonacci数的巧妙求法 (2009年05月6日)">Fibonacci数的巧妙求法</a> (2)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://jackaldire.com/200911/string-matching-with-wildcard/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
