﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-微软亚洲工程院-随笔分类-算法与程序设计</title><link>http://www.cppblog.com/littlesupersun/category/5056.html</link><description>Microsoft ATC--software design engineer</description><language>zh-cn</language><lastBuildDate>Thu, 22 May 2008 03:15:24 GMT</lastBuildDate><pubDate>Thu, 22 May 2008 03:15:24 GMT</pubDate><ttl>60</ttl><item><title>字符串替换算法和模式匹配算法</title><link>http://www.cppblog.com/littlesupersun/archive/2007/09/10/31952.html</link><dc:creator>香心晓筑</dc:creator><author>香心晓筑</author><pubDate>Mon, 10 Sep 2007 09:45:00 GMT</pubDate><guid>http://www.cppblog.com/littlesupersun/archive/2007/09/10/31952.html</guid><wfw:comment>http://www.cppblog.com/littlesupersun/comments/31952.html</wfw:comment><comments>http://www.cppblog.com/littlesupersun/archive/2007/09/10/31952.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/littlesupersun/comments/commentRss/31952.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/littlesupersun/services/trackbacks/31952.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 设有主串<font face=Times><font size=3><span lang=en-US>s</span></font></font>和子串<font face=Times><font size=3><span lang=en-US>t</span></font></font>，子串<font face=Times><font size=3><span lang=en-US>t</span></font></font>定位是指在主串<font face=Times><font size=3><span lang=en-US>s</span></font></font>中找到一个与子串<font face=Times><font size=3><span lang=en-US>t</span></font></font>相等的子串。通常把主串<font face=Times><font size=3><span lang=en-US>s</span></font></font>称为目标串，把子串<font face=Times><font size=3><span lang=en-US>t</span></font></font>称为模式串，因此定位也称作模式匹配。模式匹配成功是指在目标串<font face=Times><font size=3><span lang=en-US>s</span></font></font>中找到一个模式串<font face=Times><font size=3><span lang=en-US>t</span></font></font>。
<p style="MARGIN-BOTTOM: 0cm"><font face=Times><font size=3><span lang=en-US></span></font></font>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 传统的字符串模式匹配算法（也就是<font face=Times><font size=3><span lang=en-US>BF</span></font></font>算法）就是对于主串和模式串双双自左向右，一个一个字符比较，如果不匹配，主串和模式串的位置指针都要回溯。这样的算法时间复杂度为<font face=Times><font size=3><span lang=en-US>O</span></font></font>（<font face=Times><font size=3><span lang=en-US>n</span></font></font>＊<font face=Times><font size=3><span lang=en-US>m</span></font></font>），其中<font face=Times><font size=3><span lang=en-US>n</span></font></font>和<font face=Times><font size=3><span lang=en-US>m</span></font></font>分别为串<font face=Times><font size=3><span lang=en-US>s</span></font></font>和串<font face=Times><font size=3><span lang=en-US>t</span></font></font>的长度。</p>
<p style="MARGIN-BOTTOM: 0cm"><font face=Times><font size=3><span lang=en-US>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KMP</span> </font></font>算法是由<font face=Times><font size=3><span lang=en-US>Knuth</span></font></font>，<font face=Times><font size=3><span lang=en-US>Morris</span></font></font>和<font face=Times><font size=3><span lang=en-US>Pratt</span></font></font>等人共同提出的，所以成为<font face=Times><font size=3><span lang=en-US>Knuth</span></font></font>－<font face=Times><font size=3><span lang=en-US>Morris</span></font></font>－<font face=Times><font size=3><span lang=en-US>Pratt</span></font></font>算法，简称<font face=Times><font size=3><span lang=en-US>KMP</span></font></font>算法。<font face=Times><font size=3><span lang=en-US>KMP</span></font></font>算法是字符串模式匹配中的经典算法。和<font face=Times><font size=3><span lang=en-US>BF</span></font></font>算法相比，<font face=Times><font size=3><span lang=en-US>KMP</span></font></font>算法的不同点是匹配过程中，主串的位置指针不会回溯，这样的结果使得算法时间复杂度只为<font face=Times><font size=3><span lang=en-US>O</span></font></font>（<font face=Times><font size=3><span lang=en-US>n</span></font></font>＋<font face=Times><font size=3><span lang=en-US>m</span></font></font>）。下面说说<font face=Times><font size=3><span lang=en-US>KMP</span></font></font>算法的原理。</p>
<p style="MARGIN-BOTTOM: 0cm"><font face=Times><font size=3><span lang=en-US></span></font></font>假设我们有个模式串为&#8220;<font face=Times><font size=3><span lang=en-US>abdabcde&#8221;</span></font></font>存于数组<font face=Times><font size=3><span lang=en-US>t</span></font></font>，我们要求的就是模式串的<font face=Times><font size=3><span lang=en-US>next</span></font></font>值，见下表所示：</p>
<p style="MARGIN-BOTTOM: 0cm"><br></p>
<table borderColor=#000000 cellSpacing=0 cellPadding=4 width="100%" border=1>
    <colgroup>
    <col width=28>
    <col width=28>
    <col width=28>
    <col width=28>
    <col width=28>
    <col width=28>
    <col width=28>
    <col width=28>
    <col width=28>
    <tbody>
        <tr vAlign=top>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>i</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>0</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>1</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>2</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>3</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>4</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>5</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>6</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>7</span> </font></font></p>
            </td>
        </tr>
        <tr vAlign=top>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>t[i]</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>a</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>b</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>d</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>a</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>b</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>c</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>d</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>e</span> </font></font></p>
            </td>
        </tr>
        <tr vAlign=top>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>next[i]</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>-1</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>0</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>0</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>0</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>1</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>2</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>0</span> </font></font></p>
            </td>
            <td width="11%">
            <p><font face=Times><font size=3><span lang=en-US>0</span> </font></font></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="MARGIN-BOTTOM: 0cm"><font face=Times><font size=3><span lang=en-US></span></font></font>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 求模式<font face=Times><font size=3><span lang=en-US>t</span></font></font>的<font face=Times><font size=3><span lang=en-US>next[i]</span></font></font>（称为失效函数）的公式如下：</p>
<p style="MARGIN-BOTTOM: 0cm"><br></p>
<p style="MARGIN-BOTTOM: 0cm"><font face=Times><font size=3><span lang=en-US>next[i] =<img height=68 alt=Screenshot11.png src="http://www.blogjava.net/images/blogjava_net/kafka0102/Screenshot11.png" width=581 border=0><font face=文鼎PL细上海宋Uni></font></span> </font></font></p>
<p style="MARGIN-BOTTOM: 0cm"><font face=Times><font size=3><span lang=en-US>(</span> </font></font>上面的公式中非<font face=Times><font size=3><span lang=en-US>t</span></font></font>字母和数字组成的为数组下标<font face=Times><font size=3><span lang=en-US>)</span></font></font></p>
<p style="MARGIN-BOTTOM: 0cm"><font face=Times><font size=3><span lang=en-US></span></font></font>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 应该如何理解<font face=Times><font size=3><span lang=en-US>next</span></font></font>数组呢？在匹配过程中，如果出现不匹配的情况（当前模式串不匹配字符假定为<font face=Times><font size=3><span lang=en-US>t[i]</span></font></font>），它所对应的<font face=Times><font size=3><span lang=en-US>next[i]</span></font></font>的数值为接下来要匹配的模式串的字符的索引；也就是说，出现不匹配的情况时，模式串的索引指针要回溯到中<font face=Times><font size=3><span lang=en-US>next[i]</span></font></font>所对应的位置，而主串的索引指针保持不变。</p>
<p style="MARGIN-BOTTOM: 0cm"><font face=Times><font size=3><span lang=en-US></span></font></font>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 特别的，<font face=Times><font size=3><span lang=en-US>next</span></font></font>数组中的<font face=Times><font size=3><span lang=en-US>next[0]</span></font></font>和<font face=Times><font size=3><span lang=en-US>next[1]</span></font></font>的取值是固定的，为了标识出首字母，需要假定<font face=Times><font size=3><span lang=en-US>next[0]</span></font></font>为－<font face=Times><font size=3><span lang=en-US>1</span></font></font>（取为－<font face=Times><font size=3><span lang=en-US>1</span></font></font>是考虑到<font face=Times><font size=3><span lang=en-US>C</span></font></font>语言中的数组索引以<font face=Times><font size=3><span lang=en-US>0</span></font></font>开始）。在实现的时候，要实现公式中情况的处理需要些技巧，下面给出具体的实现：</p>
<p style="MARGIN-BOTTOM: 0cm"></p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: rgb(0,128,0)">#</span> <span style="COLOR: rgb(0,128,0)">include&nbsp;&lt;stdio.h&gt;<br>#include&nbsp;&lt;stdlib.h&gt;</span> <span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,0,0)"><br>typedef&nbsp;struct&nbsp;QString&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;char</span> <span style="COLOR: rgb(0,0,0)">*</span> <span style="COLOR: rgb(0,0,0)">&nbsp;cs;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">int</span> <span style="COLOR: rgb(0,0,0)">&nbsp;len;<br>}String;<br><br><br>void&nbsp;GetNext(String&nbsp;s</span> <span style="COLOR: rgb(0,0,0)">,</span> <span style="COLOR: rgb(0,0,255)">int</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(0,0,255)">next</span> <span style="COLOR: rgb(0,0,0)">[]){<br>&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">int</span> <span style="COLOR: rgb(0,0,0)">&nbsp;len&nbsp;</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;s</span> <span style="COLOR: rgb(0,0,0)">.</span> <span style="COLOR: rgb(0,0,0)">len;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">int</span> <span style="COLOR: rgb(0,0,0)">&nbsp;i&nbsp;</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(128,0,0)">0</span> <span style="COLOR: rgb(0,0,0)">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">int</span> <span style="COLOR: rgb(0,0,0)">&nbsp;k&nbsp;</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(0,0,0)">-</span> <span style="COLOR: rgb(128,0,0)">1</span> <span style="COLOR: rgb(0,0,0)">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">next</span> <span style="COLOR: rgb(0,0,0)">[</span> <span style="COLOR: rgb(128,0,0)">0</span> <span style="COLOR: rgb(0,0,0)">]&nbsp;</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(0,0,0)">-</span> <span style="COLOR: rgb(128,0,0)">1</span> <span style="COLOR: rgb(0,0,0)">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">while</span> <span style="COLOR: rgb(0,0,0)">(i&nbsp;</span> <span style="COLOR: rgb(0,0,0)">&lt;</span> <span style="COLOR: rgb(0,0,0)">&nbsp;len</span> <span style="COLOR: rgb(0,0,0)">-</span> <span style="COLOR: rgb(128,0,0)">1</span> <span style="COLOR: rgb(0,0,0)">){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">if</span> <span style="COLOR: rgb(0,0,0)">(k</span> <span style="COLOR: rgb(0,0,0)">==-</span> <span style="COLOR: rgb(128,0,0)">1</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(0,0,0)">||</span> <span style="COLOR: rgb(0,0,0)">&nbsp;s</span> <span style="COLOR: rgb(0,0,0)">.</span> <span style="COLOR: rgb(0,0,0)">cs[i]&nbsp;</span> <span style="COLOR: rgb(0,0,0)">==</span> <span style="COLOR: rgb(0,0,0)">&nbsp;s</span> <span style="COLOR: rgb(0,0,0)">.</span> <span style="COLOR: rgb(0,0,0)">cs[k]){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</span> <span style="COLOR: rgb(0,0,0)">++</span> <span style="COLOR: rgb(0,0,0)">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k</span> <span style="COLOR: rgb(0,0,0)">++</span> <span style="COLOR: rgb(0,0,0)">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">next</span> <span style="COLOR: rgb(0,0,0)">[i]&nbsp;</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;k;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span> <span style="COLOR: rgb(0,0,255)">else</span> <span style="COLOR: rgb(0,0,0)">{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k&nbsp;</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(0,0,255)">next</span> <span style="COLOR: rgb(0,0,0)">[k];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}<br><br><br></span><span style="COLOR: rgb(0,0,255)">int</span> <span style="COLOR: rgb(0,0,0)">&nbsp;KMPIndex(String&nbsp;s</span> <span style="COLOR: rgb(0,0,0)">,</span> <span style="COLOR: rgb(0,0,0)">String&nbsp;m){<br>&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">int</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(0,0,255)">next</span> <span style="COLOR: rgb(0,0,0)">[m</span> <span style="COLOR: rgb(0,0,0)">.</span> <span style="COLOR: rgb(0,0,0)">len]</span> <span style="COLOR: rgb(0,0,0)">,</span> <span style="COLOR: rgb(0,0,0)">i</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(128,0,0)">0</span> <span style="COLOR: rgb(0,0,0)">,</span> <span style="COLOR: rgb(0,0,0)">j</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(128,0,0)">0</span> <span style="COLOR: rgb(0,0,0)">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">int</span> <span style="COLOR: rgb(0,0,0)">&nbsp;k;<br>&nbsp;&nbsp;&nbsp;&nbsp;GetNext(m</span> <span style="COLOR: rgb(0,0,0)">,</span> <span style="COLOR: rgb(0,0,255)">next</span> <span style="COLOR: rgb(0,0,0)">);<br></span><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,0,255)">while</span> <span style="COLOR: rgb(0,0,0)">(i</span> <span style="COLOR: rgb(0,0,0)">&lt;</span> <span style="COLOR: rgb(0,0,0)">s</span> <span style="COLOR: rgb(0,0,0)">.</span> <span style="COLOR: rgb(0,0,0)">len&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,0)">&amp;&amp;</span> <span style="COLOR: rgb(0,0,0)">j</span> <span style="COLOR: rgb(0,0,0)">&lt;</span> <span style="COLOR: rgb(0,0,0)">m</span> <span style="COLOR: rgb(0,0,0)">.</span> <span style="COLOR: rgb(0,0,0)">len){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">if</span> <span style="COLOR: rgb(0,0,0)">(j</span> <span style="COLOR: rgb(0,0,0)">==-</span> <span style="COLOR: rgb(128,0,0)">1</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(0,0,0)">||</span> <span style="COLOR: rgb(0,0,0)">&nbsp;s</span> <span style="COLOR: rgb(0,0,0)">.</span> <span style="COLOR: rgb(0,0,0)">cs[i]&nbsp;</span> <span style="COLOR: rgb(0,0,0)">==</span> <span style="COLOR: rgb(0,0,0)">&nbsp;m</span> <span style="COLOR: rgb(0,0,0)">.</span> <span style="COLOR: rgb(0,0,0)">cs[j]){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</span> <span style="COLOR: rgb(0,0,0)">++</span> <span style="COLOR: rgb(0,0,0)">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j</span> <span style="COLOR: rgb(0,0,0)">++</span> <span style="COLOR: rgb(0,0,0)">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span> <span style="COLOR: rgb(0,0,255)">else</span> <span style="COLOR: rgb(0,0,0)">{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j&nbsp;</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(0,0,255)">next</span> <span style="COLOR: rgb(0,0,0)">[j];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">if</span> <span style="COLOR: rgb(0,0,0)">(j&nbsp;</span> <span style="COLOR: rgb(0,0,0)">&gt;=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;m</span> <span style="COLOR: rgb(0,0,0)">.</span> <span style="COLOR: rgb(0,0,0)">len)</span> <span style="COLOR: rgb(0,0,255)">return</span> <span style="COLOR: rgb(0,0,0)">&nbsp;i</span> <span style="COLOR: rgb(0,0,0)">-</span> <span style="COLOR: rgb(0,0,0)">m</span> <span style="COLOR: rgb(0,0,0)">.</span> <span style="COLOR: rgb(0,0,0)">len;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">else</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(0,0,255)">return</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(0,0,0)">-</span> <span style="COLOR: rgb(128,0,0)">1</span> <span style="COLOR: rgb(0,0,0)">;<br>}</span> </div>
<br><br>
<p style="MARGIN-BOTTOM: 0cm"><font face=Times><font size=3><span lang=en-US>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KMP</span> </font></font>算法也有需要改进的地方。对于模式串&#8220;<font face=Times><font size=3><span lang=en-US>aaaadd&#8221;</span></font></font>在匹配时（假定被匹配串为&#8220;<font face=Times><font size=3><span lang=en-US>aaadddd&#8221;</span></font></font>），可以看到，在匹配到索引<font face=Times><font size=3><span lang=en-US>3</span></font></font>时，主串字符为&#8220;<font face=Times><font size=3><span lang=en-US>d&#8221;</span></font></font>，模式串字符为&#8220;<font face=Times><font size=3><span lang=en-US>a&#8221;</span></font></font>，如果按照上面的做法，这时模式串只会回溯一个索引，由于仍不匹配，模式串还会回溯一个索引，直到索引位置到了首字符，主串的索引指针才会前进一位，这样就会浪费一些不必要的比较时间。出现这种情况的原因是模式串中位置<font face=Times><font size=3><span lang=en-US>i</span></font></font>的字符与<font face=Times><font size=3><span lang=en-US>next[i]</span></font></font>对应的字符相同，需要修正<font face=Times><font size=3><span lang=en-US>next[i]</span></font></font>为<font face=Times><font size=3><span lang=en-US>next[i]</span></font></font>对应的字符的索引。下面列出&#8220;<font face=Times><font size=3><span lang=en-US>aaaadd&#8221;</span></font></font>修正的<font face=Times><font size=3><span lang=en-US>nextval</span></font></font>数组的内容：</p>
<table borderColor=#000000 cellSpacing=0 cellPadding=4 width="100%" border=1>
    <colgroup>
    <col width=37>
    <col width=37>
    <col width=37>
    <col width=37>
    <col width=37>
    <col width=37>
    <col width=37>
    <tbody>
        <tr vAlign=top>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>i</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>0</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>1</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>2</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>3</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>4</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>5</span> </font></font></p>
            </td>
        </tr>
        <tr vAlign=top>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>t[i]</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>a</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>a</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>a</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>a</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>d</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>d</span> </font></font></p>
            </td>
        </tr>
        <tr vAlign=top>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>next[i]</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>-1</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>0</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>1</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>2</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>3</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>0</span> </font></font></p>
            </td>
        </tr>
        <tr vAlign=top>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>nextval[i]</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>-1</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>-1</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>-1</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>-1</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>0</span> </font></font></p>
            </td>
            <td width="14%">
            <p><font face=Times><font size=3><span lang=en-US>0</span> </font></font></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="MARGIN-BOTTOM: 0cm">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 修正函数如下：</p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: rgb(0,0,0)">void&nbsp;GetNextval(String&nbsp;s</span> <span style="COLOR: rgb(0,0,0)">,</span> <span style="COLOR: rgb(0,0,255)">int</span> <span style="COLOR: rgb(0,0,0)">&nbsp;nextval[]){<br>&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">int</span> <span style="COLOR: rgb(0,0,0)">&nbsp;len&nbsp;</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;s</span> <span style="COLOR: rgb(0,0,0)">.</span> <span style="COLOR: rgb(0,0,0)">len</span> <span style="COLOR: rgb(0,0,0)">,</span> <span style="COLOR: rgb(0,0,0)">i&nbsp;</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(128,0,0)">0</span> <span style="COLOR: rgb(0,0,0)">,</span> <span style="COLOR: rgb(0,0,0)">k&nbsp;</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(0,0,0)">-</span> <span style="COLOR: rgb(128,0,0)">1</span> <span style="COLOR: rgb(0,0,0)">;<br>&nbsp;&nbsp;&nbsp;&nbsp;nextval[</span> <span style="COLOR: rgb(128,0,0)">0</span> <span style="COLOR: rgb(0,0,0)">]&nbsp;</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(0,0,0)">-</span> <span style="COLOR: rgb(128,0,0)">1</span> <span style="COLOR: rgb(0,0,0)">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">while</span> <span style="COLOR: rgb(0,0,0)">(i&nbsp;</span> <span style="COLOR: rgb(0,0,0)">&lt;</span> <span style="COLOR: rgb(0,0,0)">&nbsp;len</span> <span style="COLOR: rgb(0,0,0)">-</span> <span style="COLOR: rgb(128,0,0)">1</span> <span style="COLOR: rgb(0,0,0)">){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">if</span> <span style="COLOR: rgb(0,0,0)">(k</span> <span style="COLOR: rgb(0,0,0)">==-</span> <span style="COLOR: rgb(128,0,0)">1</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(0,0,0)">||</span> <span style="COLOR: rgb(0,0,0)">&nbsp;s</span> <span style="COLOR: rgb(0,0,0)">.</span> <span style="COLOR: rgb(0,0,0)">cs[i]&nbsp;</span> <span style="COLOR: rgb(0,0,0)">==</span> <span style="COLOR: rgb(0,0,0)">&nbsp;s</span> <span style="COLOR: rgb(0,0,0)">.</span> <span style="COLOR: rgb(0,0,0)">cs[k]){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</span> <span style="COLOR: rgb(0,0,0)">++</span> <span style="COLOR: rgb(0,0,0)">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k</span> <span style="COLOR: rgb(0,0,0)">++</span> <span style="COLOR: rgb(0,0,0)">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: rgb(0,0,255)">if</span> <span style="COLOR: rgb(0,0,0)">(s</span> <span style="COLOR: rgb(0,0,0)">.</span> <span style="COLOR: rgb(0,0,0)">cs[i]&nbsp;</span> <span style="COLOR: rgb(0,0,0)">!=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;s</span> <span style="COLOR: rgb(0,0,0)">.</span> <span style="COLOR: rgb(0,0,0)">cs[k]){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nextval[i]&nbsp;</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;k;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span> <span style="COLOR: rgb(0,0,255)">else</span> <span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;nextval[i]&nbsp;</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;nextval[k];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span> <span style="COLOR: rgb(0,0,255)">else</span> <span style="COLOR: rgb(0,0,0)">{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k&nbsp;</span> <span style="COLOR: rgb(0,0,0)">=</span> <span style="COLOR: rgb(0,0,0)">&nbsp;nextval[k];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}</span> </div>
<br><br>谢谢某人的程序：）<br>public class CyclicExe<br>{<br>&nbsp;private int[] next=null;<br>&nbsp;<br>&nbsp;CyclicExe()<br>&nbsp;{<br>&nbsp;}<br>&nbsp;<br>&nbsp;public static void main(String[] args)<br>&nbsp;{<br>&nbsp;&nbsp;CyclicExe c=new CyclicExe();<br>&nbsp;&nbsp;StringBuffer mainString=new StringBuffer("abbabbbaaaaaccd");<br>&nbsp;&nbsp;StringBuffer oldString=new StringBuffer("abc");<br>&nbsp;&nbsp;String newString=new String("mmm");<br>&nbsp;&nbsp;c.initial(oldString);<br>&nbsp;&nbsp;int pos=0;<br>&nbsp;&nbsp;int index=0;<br>&nbsp;&nbsp;while(pos&lt;mainString.length()){<br>&nbsp;&nbsp;&nbsp;index=c.findIndex(mainString, oldString, pos);<br>&nbsp;&nbsp;&nbsp;if(index!=0){<br>&nbsp;&nbsp;&nbsp;&nbsp;mainString.replace(pos, pos+oldString.length()-1, newString);<br>&nbsp;&nbsp;&nbsp;&nbsp;pos=pos+oldString.length();<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>&nbsp;}<br>&nbsp;<br>&nbsp;void initial(StringBuffer oldString)<br>&nbsp;{<br>&nbsp;&nbsp;next=new int[oldString.length()];<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;int i=1;<br>&nbsp;&nbsp;next[1]=0;<br>&nbsp;&nbsp;int j=0;<br>&nbsp;&nbsp;while(i&lt;oldString.length()){<br>&nbsp;&nbsp;&nbsp;if(j==0||oldString.charAt(i)==oldString.charAt(j)){<br>&nbsp;&nbsp;&nbsp;&nbsp;i++;<br>&nbsp;&nbsp;&nbsp;&nbsp;j++;<br>&nbsp;&nbsp;&nbsp;&nbsp;next[i]=j;<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;j=next[j];<br>&nbsp;&nbsp;}<br>&nbsp;}<br>&nbsp;<br>&nbsp;int findIndex(StringBuffer mainString,StringBuffer oldString,int pos)<br>&nbsp;{<br>&nbsp;&nbsp;int i=pos;<br>&nbsp;&nbsp;int j=1;<br>&nbsp;&nbsp;while(i&lt;mainString.length()&amp;&amp;j&lt;oldString.length())<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;if(j==0||mainString.charAt(i)==oldString.charAt(j)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;i++;<br>&nbsp;&nbsp;&nbsp;&nbsp;j++;<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;j=next[j];<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;if(j&gt;oldString.length()) return i-oldString.length();<br>&nbsp;&nbsp;else return 0;<br>&nbsp;}<br>&nbsp;<br>}
<img src ="http://www.cppblog.com/littlesupersun/aggbug/31952.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/littlesupersun/" target="_blank">香心晓筑</a> 2007-09-10 17:45 <a href="http://www.cppblog.com/littlesupersun/archive/2007/09/10/31952.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一道微软的面试题（数学运算方面的）</title><link>http://www.cppblog.com/littlesupersun/archive/2007/08/31/31292.html</link><dc:creator>香心晓筑</dc:creator><author>香心晓筑</author><pubDate>Fri, 31 Aug 2007 05:40:00 GMT</pubDate><guid>http://www.cppblog.com/littlesupersun/archive/2007/08/31/31292.html</guid><wfw:comment>http://www.cppblog.com/littlesupersun/comments/31292.html</wfw:comment><comments>http://www.cppblog.com/littlesupersun/archive/2007/08/31/31292.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/littlesupersun/comments/commentRss/31292.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/littlesupersun/services/trackbacks/31292.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; a b c d e&nbsp; <br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * f&nbsp; <br>&nbsp;&nbsp; ______________&nbsp; <br>&nbsp;&nbsp; ＝g g g g g g&nbsp; <br>&nbsp;<br>问，a b c d e f g各是什么数字（不重复）<br><br></p>
<p>算法解答：111111=3*7*11*13*37 <br>因为 f!=g&amp;&amp;gggggg%f==0&amp;&amp;f&lt;10 <br>所以 f==3||f==7 <br>&nbsp;<br>另外 abcde&lt;111111 &amp;&amp; abcde*f==111111*g <br>所以 g&lt;f <br>&nbsp;<br>f==7时g==6 <br>f==3时无解 <br></p>
<img src ="http://www.cppblog.com/littlesupersun/aggbug/31292.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/littlesupersun/" target="_blank">香心晓筑</a> 2007-08-31 13:40 <a href="http://www.cppblog.com/littlesupersun/archive/2007/08/31/31292.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>