﻿<?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++博客-wuzimian-随笔分类-算法相关</title><link>http://www.cppblog.com/wuzimian/category/19405.html</link><description>努力努力再努力，坚持坚持再坚持</description><language>zh-cn</language><lastBuildDate>Sun, 03 Jun 2012 04:55:56 GMT</lastBuildDate><pubDate>Sun, 03 Jun 2012 04:55:56 GMT</pubDate><ttl>60</ttl><item><title>欧几里德算法 贝祖等式  扩展欧几里德算法</title><link>http://www.cppblog.com/wuzimian/archive/2012/06/02/177218.html</link><dc:creator>吴自勉</dc:creator><author>吴自勉</author><pubDate>Sat, 02 Jun 2012 09:53:00 GMT</pubDate><guid>http://www.cppblog.com/wuzimian/archive/2012/06/02/177218.html</guid><wfw:comment>http://www.cppblog.com/wuzimian/comments/177218.html</wfw:comment><comments>http://www.cppblog.com/wuzimian/archive/2012/06/02/177218.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wuzimian/comments/commentRss/177218.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wuzimian/services/trackbacks/177218.html</trackback:ping><description><![CDATA[计算机程序设计艺术开篇便提到了“欧几里德”算法，也就是中国的“辗转相除法”。<br />这个是个古老、经典的算法。<br />说的是：两个正整数 a，b（设a&gt;b）求出他们的最大公约数。<br />算法步骤：<br />1. r=a mod b    （mod是相除取余数的意思）<br />2.如果r=0，则b是最大公约数，否则转3<br />3.a=b ，b=r  转 1<br />算法的一种证明：<br />证：<br />    要证欧几里德算法成立，即证: gcd(a,b)=gcd(b,r),其中 gcd是取最大公约数的意思，r=a mod b<br />    下面证 gcd（a，b）=gcd（b，r）<br />    设  c是a，b的最大公约数，即c=gcd（a，b），则有 a=mc，b=nc，其中m，n为正整数，且m，n互为质数<br />    由 r= a mod b可知，r= a- qb 其中，q是正整数，<br />    则 r=a-qb=mc-qnc=（m-qn）c<br />    b=nc,r=(m-qn)c，且n，（m-qn）互质（假设n，m-qn不互质，则n=xd, m-qn=yd 其中x,y,d都是正整数，且d&gt;1<br />                                                                则a=mc=(qx+y)dc, b=xdc,这时a,b 的最大公约数变成dc，与前提矛盾，<br />                                                                 所以n ，m-qn一定互质）<br />    则gcd（b,r）=c=gcd（a,b）<br />    得证。<br /><br /><p><span style="font-size: small;"><span style="color: #0000ff;"><strong>定理2</strong></span></span>：（由法国数学家拉梅证明）欧几里得算法所需除法次数不超过m和n中较小的那个数的十进制位数的5倍</p><p><span style="color: #0000ff;"><strong><span style="font-size: small;">定理3：</span></strong></span>欧几里得算法所需除法次数不超过2 log(n+1)，其中n为较小的数</p><br />由欧几里德算法，衍生出来一个重要的贝祖等式：两数的最大公约数可以用两数的整数倍相加来表示，如21 = gcd(105,252)=5 × 105 + (−2） × 252。<br />贝祖等式的<font color="#FF0000">非严格证明</font>：<br />证明：<br />我们可以将辗转相除法的步骤看成：<br />a      = p(0)b + r(0)
  <br />b      = p(1)r(0)+r(1)<br />r(0)   = p(2)r(1)+r(2)
  <br />r(1)   = p(3)r2+r(3)<br />......<br />r(n-2)= p(n)r(n-1)+ r(n)
<br />  r(n-1)= p(n+1)r(n)+ r(n+1)
<br />  r(n)   = p(n+2)r(n+1)<br />当我们做到最后一个式子的时候，我们就知道 gcd(a，b)=r(n+1);<br />由倒数第二个式子，我们可知：r(n+1)
=gcd(a,b)=r(n-1) - p(n+1)r(n),其中r(n)又可以用上面的式子r(n)=r(n-2)-p(n)r(n-1)代替，就这样不断地用上面的式子代替，<br />到最后我们就可以得到gcd(a,b)关于a，b的一次的关系式。<br />得证.<br /><br />现在我们已经知道 存在 x，y使得 ax+by=gcd(a，b)成立了，那么怎样更直接地求x，y呢？<br />设： a*x1+b*y1=gcd(a,b)<br />       b*x2+(a mod b)*y2=gcd(b,(a mod b))<br />我们已经知道了：gcd(a,b)=gcd(b,(a mod b))<br />那么有：a*x1+b*y1=b*x2+(a mod b)*y2=b*x2+(a-a/b*b)*y2=b*x2 +a*y2- a/b*b*y2=a*y2+b*(x2-a/b*y2)<br />那么我们有：x1=y2 ;   y1=x2-a/b*y2, 这样就把求x1,y1的问题，转化为求b*x2+(a mod b)*y2=gcd(a,b)中x2,y2的问题。<br />这个思路是基于递归的思想的。因为 gcd 不断的递归求解一定会有个时候 b=0，所以递归可以结束。<br />基于递归实现的C++代码：<br /><div style="background-color:#eeeeee;font-size:13px;BORDER:1px solid #CCCCCC;PADDING-RIGHT: 5px;PADDING-BOTTOM: 4px;PADDING-left: 4px;PADDING-TOP: 4px;WIDTH: 98%;word-break:break-all"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000; ">#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">iostream</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #000000; "></span><span style="color: #0000FF; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #0000FF; ">using</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">namespace</span><span style="color: #000000; "> std;<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> x</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,y</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,gcd</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> qq(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> ,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> main()<br />{   <br />    </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> a,b;<br />    cin</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">a</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">b;//输入的时候保证a&gt;b，a，b是正整数就好了就好了，我这里没再检查a，b的有效性。<br />    qq(a,b);<br />    cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">x</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">*</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">a</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">+</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">y</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">*</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">b</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">=</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">x</span><span style="color: #000000; ">*</span><span style="color: #000000; ">a</span><span style="color: #000000; ">+</span><span style="color: #000000; ">y</span><span style="color: #000000; ">*</span><span style="color: #000000; ">b</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">=</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">gcd</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br /><br /><br />    </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> </span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />}<br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> qq(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> a,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> b)<br />{<br />    </span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(</span><span style="color: #000000; ">0</span><span style="color: #000000; ">==</span><span style="color: #000000; ">b)<br />    {<br />        x</span><span style="color: #000000; ">=</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />        y</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />        gcd</span><span style="color: #000000; ">=</span><span style="color: #000000; ">a;<br />        </span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br />    }<br />    </span><span style="color: #0000FF; ">else</span><span style="color: #000000; "><br />    {<br />        qq(b,a</span><span style="color: #000000; ">%</span><span style="color: #000000; ">b);<br />        </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> temp</span><span style="color: #000000; ">=</span><span style="color: #000000; ">x;<br />        x</span><span style="color: #000000; ">=</span><span style="color: #000000; ">y;<br />        y</span><span style="color: #000000; ">=</span><span style="color: #000000; ">temp</span><span style="color: #000000; ">-</span><span style="color: #000000; ">a</span><span style="color: #000000; ">/</span><span style="color: #000000; ">b</span><span style="color: #000000; ">*</span><span style="color: #000000; ">y;<br />        </span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br />    }<br /><br />}</span></div><br />循环版本：<br /><div style="background-color:#eeeeee;font-size:13px;BORDER:1px solid #CCCCCC;PADDING-RIGHT: 5px;PADDING-BOTTOM: 4px;PADDING-left: 4px;PADDING-TOP: 4px;WIDTH: 98%;word-break:break-all"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000; ">#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">iostream</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #000000; "></span><span style="color: #0000FF; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #0000FF; ">using</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">namespace</span><span style="color: #000000; "> std;<br /><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> qq(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> ,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> main()<br />{   <br />    </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> a,b;<br />    cin</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">a</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">b;<br />    qq(a,b);<br /><br />    </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> </span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />}<br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> qq(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> a,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> b)<br />{<br />    </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> x</span><span style="color: #000000; ">=</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,y</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,gcd</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;  //<br />    </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> temp[</span><span style="color: #000000; ">100</span><span style="color: #000000; ">][</span><span style="color: #000000; ">2</span><span style="color: #000000; ">];    //记录过程中的a，b <br />    </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> counter</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />    </span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(b</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)<br />    {<br />        temp[counter][</span><span style="color: #000000; ">0</span><span style="color: #000000; ">]</span><span style="color: #000000; ">=</span><span style="color: #000000; ">a;<br />        temp[counter][</span><span style="color: #000000; ">1</span><span style="color: #000000; ">]</span><span style="color: #000000; ">=</span><span style="color: #000000; ">b;<br />        counter</span><span style="color: #000000; ">++</span><span style="color: #000000; ">;<br />        </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> tempnum</span><span style="color: #000000; ">=</span><span style="color: #000000; ">a;<br />        a</span><span style="color: #000000; ">=</span><span style="color: #000000; ">b;<br />        b</span><span style="color: #000000; ">=</span><span style="color: #000000; ">tempnum</span><span style="color: #000000; ">%</span><span style="color: #000000; ">b;<br />    }<br /><br />    gcd </span><span style="color: #000000; ">=</span><span style="color: #000000; ">a;<br />    cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">gcd</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br />    </span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> i</span><span style="color: #000000; ">=--</span><span style="color: #000000; ">counter;i</span><span style="color: #000000; ">&gt;=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;i</span><span style="color: #000000; ">--</span><span style="color: #000000; ">)<br />    {   <br />        </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> tempnum</span><span style="color: #000000; ">=</span><span style="color: #000000; ">x;<br />        x</span><span style="color: #000000; ">=</span><span style="color: #000000; ">y;<br />        y</span><span style="color: #000000; ">=</span><span style="color: #000000; ">tempnum</span><span style="color: #000000; ">-</span><span style="color: #000000; ">temp[i][</span><span style="color: #000000; ">0</span><span style="color: #000000; ">]</span><span style="color: #000000; ">/</span><span style="color: #000000; ">temp[i][</span><span style="color: #000000; ">1</span><span style="color: #000000; ">]</span><span style="color: #000000; ">*</span><span style="color: #000000; ">y;<br />    }<br />   cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">x</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">*</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">temp[</span><span style="color: #000000; ">0</span><span style="color: #000000; ">][</span><span style="color: #000000; ">0</span><span style="color: #000000; ">]</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">+</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">y</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">*</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">temp[</span><span style="color: #000000; ">0</span><span style="color: #000000; ">][</span><span style="color: #000000; ">1</span><span style="color: #000000; ">]</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">=</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">x</span><span style="color: #000000; ">*</span><span style="color: #000000; ">temp[</span><span style="color: #000000; ">0</span><span style="color: #000000; ">][</span><span style="color: #000000; ">0</span><span style="color: #000000; ">]</span><span style="color: #000000; ">+</span><span style="color: #000000; ">y</span><span style="color: #000000; ">*</span><span style="color: #000000; ">temp[</span><span style="color: #000000; ">0</span><span style="color: #000000; ">][</span><span style="color: #000000; ">1</span><span style="color: #000000; ">]</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">=</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">gcd</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br /><br />}</span></div>以上求解x，y的过程我们不妨把它称为“扩展欧几里德算法”，当然我这种说法很不好，为什么呢？<br />在《计算机程序设计艺术》第一卷 1.2 数学准备 这个小节里面，Knuth先生给出了一个十分优美的“扩展欧几里德算法”<br />如下：<br /><br /><br />扩展的欧几里德算法：给定两个正整数m和n，我们计算它们的最大公约数和两个整数a和b，使am+bn=d；<br />E1：【初始化】a0=b=1； a=b0=0； c=m；d=n；<br />E2：【除】q=c/d；r=c%d<br />E3：【余数为0？】如果 r=0；算法终止，在这种情况下，我们如愿地有：am+bn=d；<br />E4：【循环】c=d；  d=r； t=a0；  a0=a;   a=t-qa;    t=b0;    b0=b;   b=t-qb,    返回E2<br />END；<br /><br />关于这个算法，Knuth先生也给出了优美的证明，我这里不再赘言；<br />下面给出实现代码：<br /><br /><div style="background-color:#eeeeee;font-size:13px;BORDER:1px solid #CCCCCC;PADDING-RIGHT: 5px;PADDING-BOTTOM: 4px;PADDING-left: 4px;PADDING-TOP: 4px;WIDTH: 98%;word-break:break-all"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000; ">#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">iostream</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /><br /></span><span style="color: #0000FF; ">using</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">namespace</span><span style="color: #000000; "> std;<br /><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> qq(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> ,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> main()<br />{   <br />    </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> m,n;<br />    cin</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">m</span><span style="color: #000000; ">&gt;&gt;</span><span style="color: #000000; ">n;//这里同样没有检查m、n有效性，自己保证m&gt;n,都是正整数<br />    qq(m,n);<br /><br />    </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> </span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />}<br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> qq(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> m,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> n)<br />{<br />    </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> a</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,b</span><span style="color: #000000; ">=</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,a0</span><span style="color: #000000; ">=</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,b0</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />    </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> c</span><span style="color: #000000; ">=</span><span style="color: #000000; ">m,d</span><span style="color: #000000; ">=</span><span style="color: #000000; ">n;<br /><br />    </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> q</span><span style="color: #000000; ">=</span><span style="color: #000000; ">c</span><span style="color: #000000; ">/</span><span style="color: #000000; ">d;<br />    </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> r</span><span style="color: #000000; ">=</span><span style="color: #000000; ">c</span><span style="color: #000000; ">%</span><span style="color: #000000; ">d;<br /><br />    </span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(r</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)<br />    {<br />         c</span><span style="color: #000000; ">=</span><span style="color: #000000; ">d;<br />         d</span><span style="color: #000000; ">=</span><span style="color: #000000; ">r;<br />         </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> t</span><span style="color: #000000; ">=</span><span style="color: #000000; ">a0;<br />         a0</span><span style="color: #000000; ">=</span><span style="color: #000000; ">a;<br />         a</span><span style="color: #000000; ">=</span><span style="color: #000000; ">t</span><span style="color: #000000; ">-</span><span style="color: #000000; ">q</span><span style="color: #000000; ">*</span><span style="color: #000000; ">a;<br /><br />         t</span><span style="color: #000000; ">=</span><span style="color: #000000; ">b0;<br />         b0</span><span style="color: #000000; ">=</span><span style="color: #000000; ">b;<br />         b</span><span style="color: #000000; ">=</span><span style="color: #000000; ">t</span><span style="color: #000000; ">-</span><span style="color: #000000; ">q</span><span style="color: #000000; ">*</span><span style="color: #000000; ">b;<br /><br />         q</span><span style="color: #000000; ">=</span><span style="color: #000000; ">c</span><span style="color: #000000; ">/</span><span style="color: #000000; ">d;<br />         r</span><span style="color: #000000; ">=</span><span style="color: #000000; ">c</span><span style="color: #000000; ">%</span><span style="color: #000000; ">d;<br /><br />    }<br />    cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">a=</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">a</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">  b=</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">b</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">  d=</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">d</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br />}</span></div>我们可以看到这个算法的实现起来非常的简洁、明了！<br />求解同样的问题，算法不同，会有相当大的差别。<br />程序=算法+数据结构<br /><br />&lt;全文完&gt;<br /><br /><br /><br /><br /><br /><br /><img src ="http://www.cppblog.com/wuzimian/aggbug/177218.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wuzimian/" target="_blank">吴自勉</a> 2012-06-02 17:53 <a href="http://www.cppblog.com/wuzimian/archive/2012/06/02/177218.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>来自圣经的算法【转载】</title><link>http://www.cppblog.com/wuzimian/archive/2012/06/02/177191.html</link><dc:creator>吴自勉</dc:creator><author>吴自勉</author><pubDate>Sat, 02 Jun 2012 05:37:00 GMT</pubDate><guid>http://www.cppblog.com/wuzimian/archive/2012/06/02/177191.html</guid><wfw:comment>http://www.cppblog.com/wuzimian/comments/177191.html</wfw:comment><comments>http://www.cppblog.com/wuzimian/archive/2012/06/02/177191.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wuzimian/comments/commentRss/177191.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wuzimian/services/trackbacks/177191.html</trackback:ping><description><![CDATA[本文转载自：http://www.matrix67.com/blog/archives/3748<br /><br />原文如下：<br />《来自圣经的证明》收集了数十个简洁而优雅的数学证明，迅速赢得了大批数学爱好者的追捧。如果还有一本《来自圣经的算法》，哪些算法会列入其中呢？最近，有人在 <a href="http://cstheory.stackexchange.com/questions/189/algorithms-from-the-book">StackExchange</a> 上发起了提问，向网友们征集那些来自圣经的算法。众人在一大堆入围算法中进行投票，最终得出了呼声最高的五个算法：
<p><strong>第五名： BFPRT 算法</strong><br />
    1973 年， Blum 、 Floyd 、 Pratt 、 Rivest 、 Tarjan 集体出动，合写了一篇题为 “Time 
bounds for selection” 的论文，给出了一种在数组中选出第 k 大元素的算法，俗称"中位数之中位数算法"。依靠一种精心设计的 
pivot 选取方法，该算法从理论上保证了最坏情形下的线性时间复杂度，打败了平均线性、最坏 O(n^2) 
复杂度的传统算法。一群大牛把递归算法的复杂度分析玩弄于</p><del datetime="2010-09-29T05:21:01+00:00">骨掌</del>股掌之间，构造出了一个当之无愧的来自圣经的算法。<p><span id="more-3748"></span><br /><strong>第四名：快速排序</strong><br />
    快速排序算法是 1960 年由英国计算机科学家 C.A.R. Hoare 
发明的，是一种既高效又简洁的排序方法，现在已是学习算法的必修内容之一。快速排序的思想并不复杂，妙就妙在那个线性的数据分割过程，而真正最牛 B 
的则是对整个算法的时间复杂度分析。我曾写过一个<a href="http://www.matrix67.com/blog/archives/172">快速排序平均 O(n log n) 的证明</a>，分析过程绝对值得欣赏。</p><p> <br /><strong>第三名：并查集</strong><br />
    严格地说，并查集是一种数据结构，它专门用来处理集合的合并操作和查询操作。并查集巧妙地借用了树结构，使得编程复杂度降低到了令人难以置信的地
步；用上一些递归技巧后，各种操作几乎都能用两行代码搞定。而路径压缩的好主意，更是整个数据结构的画龙点睛之笔。并查集的效率极高，单次操作的时间复杂
度几乎可以看作是常数级别；但由于数据结构的实际行为难以预测，精确的时间复杂度分析需要用到不少高深的技巧。</p><p> <br /><strong>第二名： KMP 算法</strong><br />
    KMP 算法是一种非常有效的字符串匹配算法，它告诉了人们一个有些反直觉的事实：字符串匹配竟然能在线性时间里完成！整个算法写成代码不足 10 行，但其中蕴含的天才般的奇妙思想让算法初学者们望而却步，而它的复杂度分析则更是堪称经典。</p><p> <br /><strong>第一名：辗转相除法</strong><br />
    辗转相除法是 Euclid 
的《几何原本》中提到的一种寻找两个数的最大公因数的算法。无论是简洁的算法过程，还是深刻的算法原理，抑或是巧妙的复杂度分析，都称得上是来自圣经的算
法。而扩展的辗转相除法则构造性地证明了，对任意整数 a 和 b ，存在一对 x 、 y 使得 ax + by = gcd(a, b) 
。这一结论的普遍性和实用性让它成为了数论中的基本定理之一，在很多数学问题中都能看到它的身影。</p><br /><img src ="http://www.cppblog.com/wuzimian/aggbug/177191.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wuzimian/" target="_blank">吴自勉</a> 2012-06-02 13:37 <a href="http://www.cppblog.com/wuzimian/archive/2012/06/02/177191.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>