﻿<?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/lshain/category/18509.html</link><description>Beyond this world...</description><language>zh-cn</language><lastBuildDate>Fri, 27 Jan 2012 05:37:05 GMT</lastBuildDate><pubDate>Fri, 27 Jan 2012 05:37:05 GMT</pubDate><ttl>60</ttl><item><title>KMP_Manacher 思想</title><link>http://www.cppblog.com/lshain/articles/164573.html</link><dc:creator>Lshain</dc:creator><author>Lshain</author><pubDate>Fri, 27 Jan 2012 04:41:00 GMT</pubDate><guid>http://www.cppblog.com/lshain/articles/164573.html</guid><wfw:comment>http://www.cppblog.com/lshain/comments/164573.html</wfw:comment><comments>http://www.cppblog.com/lshain/articles/164573.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lshain/comments/commentRss/164573.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lshain/services/trackbacks/164573.html</trackback:ping><description><![CDATA[<div>KMP: <br />
&nbsp;&nbsp;&nbsp; 字符串匹配，朴素的匹配是直接暴力，暴力会产生多余的匹配，没有利用到匹配串自身的特点，KMP优化，先求出匹配串自身的最长覆盖字串，每次匹配失败时，直接跳到下一个可能匹配的位置。避免多余的匹配。关键点：计算匹配串每个字符匹配失败时，跳到的位置。<br />
eg:&nbsp;<br />
asde<span style="color: #ff0000">abca</span><span style="color: #ff0000">b</span>cdefa&nbsp;&nbsp;&nbsp; a 和 t 匹配失败 跳到下一个可能产生匹配的位置&nbsp;&nbsp;&nbsp;&nbsp; asdeabc<span style="color: #ff0000">abcd</span><span style="color: #ff0000">e</span>fasdfg&nbsp;<br />
&nbsp;
&nbsp; &nbsp; &nbsp;<span style="color: #ff0000">abct</span><span style="color: #ff0000">e</span> &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; -----------------------------------------------&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000">abcte</span><br />
<br />
Manacher:<br />
&nbsp;&nbsp;&nbsp; 字符串回文计算，朴素的方式是直接暴力，枚举每个点，然后向两边扩展, Manacher思想，利用回文本身的特点，跳过多余的字符比较。<br />
&nbsp;&nbsp;&nbsp; 朴素和Manacher方式，都先预处理一下字符串，eg: "asdfx" -&gt; "$#a#s#d#f#x#" 消除字符串长度分奇偶的麻烦<br />
&nbsp;&nbsp;&nbsp; 朴素方式_O(n^2): s字符串数组，l记录每个位置，以该位置为中心的回文半径<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for i =&nbsp;1 -&gt; n<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; l[i] = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while( s[i - l[i]]&nbsp;== s[i + l[i]] )l[i]++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;Manacher_O(n): 记录向右扩展的最右端位置，和索引<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for i =&nbsp;1 -&gt; n<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( maxRight &gt; i )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
<span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Manacher优化关键：(ind&lt;&lt;1) - i 为 i 位置 关于 ind 位置 的 对称位置</span><br />
<span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // maxRight&nbsp;- i 为 i位置 到 记录的最右端的距离</span><br />
<span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 可以想到 l[i] 最小为 以上两者的最小值，这就跳过了 多余的 比较</span><br />
<span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l[i] = l[(ind&lt;&lt;1) - i] &lt; (maxRight&nbsp;- i) ? l[(ind&lt;&lt;1) - i]&nbsp;: (maxRight&nbsp;- i);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; l[i] = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while( s[i - l[i]]&nbsp;== s[i + l[i]] )l[i]++;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( i + l[i] &gt; maxRight )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxRight = i + l[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ind = i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </div>
<img src ="http://www.cppblog.com/lshain/aggbug/164573.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lshain/" target="_blank">Lshain</a> 2012-01-27 12:41 <a href="http://www.cppblog.com/lshain/articles/164573.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>