﻿<?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++博客-技术无极限-随笔分类-C/C++/算法</title><link>http://www.cppblog.com/xinxin/category/12082.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 22 Jan 2010 04:38:29 GMT</lastBuildDate><pubDate>Fri, 22 Jan 2010 04:38:29 GMT</pubDate><ttl>60</ttl><item><title>多态~~我一直没有形成理论化的知识</title><link>http://www.cppblog.com/xinxin/archive/2010/01/19/105988.html</link><dc:creator>勇敢空心人</dc:creator><author>勇敢空心人</author><pubDate>Tue, 19 Jan 2010 01:39:00 GMT</pubDate><guid>http://www.cppblog.com/xinxin/archive/2010/01/19/105988.html</guid><wfw:comment>http://www.cppblog.com/xinxin/comments/105988.html</wfw:comment><comments>http://www.cppblog.com/xinxin/archive/2010/01/19/105988.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xinxin/comments/commentRss/105988.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xinxin/services/trackbacks/105988.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 多态<br>重载&nbsp;&nbsp;<a href='http://www.cppblog.com/xinxin/archive/2010/01/19/105988.html'>阅读全文</a><img src ="http://www.cppblog.com/xinxin/aggbug/105988.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xinxin/" target="_blank">勇敢空心人</a> 2010-01-19 09:39 <a href="http://www.cppblog.com/xinxin/archive/2010/01/19/105988.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用辗转相除法求两个自然数的最大公因数</title><link>http://www.cppblog.com/xinxin/archive/2009/10/21/99094.html</link><dc:creator>勇敢空心人</dc:creator><author>勇敢空心人</author><pubDate>Wed, 21 Oct 2009 02:51:00 GMT</pubDate><guid>http://www.cppblog.com/xinxin/archive/2009/10/21/99094.html</guid><wfw:comment>http://www.cppblog.com/xinxin/comments/99094.html</wfw:comment><comments>http://www.cppblog.com/xinxin/archive/2009/10/21/99094.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xinxin/comments/commentRss/99094.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xinxin/services/trackbacks/99094.html</trackback:ping><description><![CDATA[<p>利用辗转相除法求两个自然数的最大公因数 程序如下：<br>//利用辗转相除法求两个自然数的最大公因数<br>int gcd(int a, int b)<br>{<br>&nbsp;&nbsp;&nbsp; int r;<br>&nbsp;&nbsp;&nbsp; while(b)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r = a%b;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a = b;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b = r;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return a;<br>}</p>
<p>相关理论如下：<br>&nbsp;&nbsp;&nbsp; 「辗转相除法」又叫做「欧几里得算法」，是公元前 300 年左右的希腊数学家欧几里得在他的著作《几何原本》提出的。利用这个方法,可以较快地求出两个自然数的最大公因数，即 HCF 或叫做 gcd。所谓最大公因数，是指几个数的共有的因数之中最大的一个，例如 8 和 12 的最大公因数是 4，记作 gcd(8,12)=4。<br>&nbsp;&nbsp;&nbsp; 在介绍这个方法之前,先说明整除性的一些特点,注以下文的所有数都是正整数,以后不再重覆.<br>&nbsp;&nbsp;&nbsp; 我们可以这样给出整除以的定义:<br>&nbsp;&nbsp;&nbsp; 对於两个自然数 a 和 b，若存在正整数 q，使得 a=bq，则 b 能整除 a，记作 b | a，我们叫 b 是 a 的因数，而 a 是 b 的倍数。那麼如果 c | a，而且 c | b，则 c 是 a 和 b 的公因数。<br>&nbsp;&nbsp;&nbsp; 由此,我们可以得出以下一些推论：<br>&nbsp;&nbsp;&nbsp; 推论一：如果 a | b，若 k 是整数，则 a | kb。因为由 a | b 可知 ha=b，所以 (hk)a=kb，即 a | kb.<br>&nbsp;&nbsp;&nbsp; 推论二：如果 a | b 以及 a | c，则 a | (b&#177;c)。因为由 a | b 以及 a | c，可知 ha=b，ka=c，二式相加,得 (h+k)a=b+c,即 a | (b+c).同样把二式相减可得 a | (b-c)。<br>&nbsp;&nbsp;&nbsp; 推论三：如果 a | b 以及 b | a，则 a=b。因为由 a | b 以及 b | a，可知 ha=b，a=kb，因此 a=k(ha)，hk=1，由於 h 和 k 都是正整数，故 h=k=1，因此 a=b。</p>
<p>&nbsp;&nbsp;&nbsp; 辗转相除法是用来计算两个数的最大公因数，在数值很大时尤其有用而且应用在电脑程式上也十分简单。其理论如下：<br>&nbsp;&nbsp;&nbsp; 如果 q 和 r 是 m 除以 n 的商及余数，即 m=nq+r，则 gcd(m,n)=gcd(n,r)。&nbsp;&nbsp;&nbsp; 证明是这样的:<br>&nbsp;&nbsp;&nbsp; 设 a=gcd(m,n)，b=gcd(n,r)<br>&nbsp;&nbsp;&nbsp; 则由 a | m 及 a | n，可得 a | (m-nq)(由推论一及推论二得出的)，即 a | r ，又 a | n，所以 a | b。<br>&nbsp;&nbsp;&nbsp; 由 b | r 及 b | n，可得 b | (nq+r)，即 b | m，又 b | n，所以b | a。<br>&nbsp;&nbsp;&nbsp; 因为 a | b 并且 b | a，所以 a=b，即 gcd(m,n)=gcd(n,r)。 </p>
<p>举例计算 gcd(546, 429),由於 546=1(429)+117,429=3(117)+78,117=1(78)+39,78=2(39),因此<br>gcd(546, 429)<br>=gcd(429, 117)<br>=gcd(117, 78)<br>=gcd(78, 39)<br>=39<br><br><br><br>此处再添加一个程序例子，不过不是利用辗转相除法<br>求最大公约数和最小公倍数:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #include &lt;iostream&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using namespace std;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int gec,lcm;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void process(int x,int y)<br>&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;gcd=x&lt;y?x:y;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lcm=x&lt;y?y:x;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(gcd=x&lt;y?x:y;gcd&gt;1;gcd--)if(x%gcd==0&amp;&amp;y%gcd==0)break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(lcm=x&lt;y?x:y;lcm&gt;1;lcm++)if(lcm%x==0&amp;&amp;lcm%y==0)break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<img src ="http://www.cppblog.com/xinxin/aggbug/99094.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xinxin/" target="_blank">勇敢空心人</a> 2009-10-21 10:51 <a href="http://www.cppblog.com/xinxin/archive/2009/10/21/99094.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>printf/scanf格式控制符的完整格式</title><link>http://www.cppblog.com/xinxin/archive/2009/10/18/98891.html</link><dc:creator>勇敢空心人</dc:creator><author>勇敢空心人</author><pubDate>Sun, 18 Oct 2009 10:38:00 GMT</pubDate><guid>http://www.cppblog.com/xinxin/archive/2009/10/18/98891.html</guid><wfw:comment>http://www.cppblog.com/xinxin/comments/98891.html</wfw:comment><comments>http://www.cppblog.com/xinxin/archive/2009/10/18/98891.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xinxin/comments/commentRss/98891.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xinxin/services/trackbacks/98891.html</trackback:ping><description><![CDATA[<p><font color=#0000ff>printf的格式控制的完整格式：<br>%&nbsp; -&nbsp; 0&nbsp; m.n&nbsp; l或h&nbsp; 格式字符<br>下面对组成格式说明的各项加以说明：<br>①%：表示格式说明的起始符号，不可缺少。<br>②-：有-表示左对齐输出，如省略表示右对齐输出。<br>③0：有0表示指定空位填0,如省略表示指定空位不填。<br>④m.n：m指域宽，即对应的输出项在输出设备上所占的字符数。N指精度。用于说明输出的实型数的小数位数。为指定n时，隐含的精度为n=6位。<br>⑤l或h:l对整型指long型，对实型指double型。h用于将整型的格式字符修正为short型。<br><br>－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br><strong>格式字符</strong><br>格式字符用以指定输出项的数据类型和输出格式。<br>&nbsp;①d格式：用来输出十进制整数。有以下几种用法：<br>%d：按整型数据的实际长度输出。<br>%md：m为指定的输出字段的宽度。如果数据的位数小于m，则左端补以空格，若大于m，则按实际位数输出。<br>%ld：输出长整型数据。<br>②o格式：以无符号八进制形式输出整数。对长整型可以用"%lo"格式输出。同样也可以指定字段宽度用&#8220;%mo&#8221;格式输出。<br>例：<br>&nbsp;&nbsp; main()<br>&nbsp;&nbsp; { int a = -1;<br>&nbsp;&nbsp;&nbsp;&nbsp; printf("%d, %o", a, a);<br>&nbsp;&nbsp; }<br>&nbsp; 运行结果：-1,177777<br>&nbsp; 程序解析：-1在内存单元中（以补码形式存放）为(1111111111111111)2，转换为八进制数为(177777)8。<br>③x格式：以无符号十六进制形式输出整数。对长整型可以用"%lx"格式输出。同样也可以指定字段宽度用"%mx"格式输出。<br>④u格式：以无符号十进制形式输出整数。对长整型可以用"%lu"格式输出。同样也可以指定字段宽度用&#8220;%mu&#8221;格式输出。<br>⑤c格式：输出一个字符。<br>⑥s格式：用来输出一个串。有几中用法<br>%s：例如:printf("%s", "CHINA")输出"CHINA"字符串（不包括双引号）。<br>%ms：输出的字符串占m列，如字符串本身长度大于m，则突破获m的限制,将字符串全部输出。若串长小于m，则左补空格。<br>%-ms：如果串长小于m，则在m列范围内，字符串向左靠，右补空格。<br>%m.ns：输出占m列，但只取字符串中左端n个字符。这n个字符输出在m列的右侧，左补空格。<br>%-m.ns：其中m、n含义同上，n个字符输出在m列范围的左侧，右补空格。如果n&gt;m，则自动取n值，即保证n个字符正常输出。<br>⑦f格式：用来输出实数（包括单、双精度），以小数形式输出。有以下几种用法：<br>%f：不指定宽度，整数部分全部输出并输出6位小数。<br>%m.nf：输出共占m列，其中有n位小数，如数值宽度小于m左端补空格。&nbsp;<br>%-m.nf：输出共占n列，其中有n位小数，如数值宽度小于m右端补空格。<br>⑧e格式：以指数形式输出实数。可用以下形式：<br>%e：数字部分（又称尾数）输出6位小数，指数部分占5位或4位。<br>%m.ne和%-m.ne：m、n和&#8221;-&#8221;字符含义与前相同。此处n指数据的数字部分的小数位数，m表示整个输出数据所占的宽度。<br>⑨g格式：自动选f格式或e格式中较短的一种输出，且不输出无意义的零。<br><br>－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br>关于printf函数的进一步说明：<br>如果想输出字符"%",则应该在&#8220;格式控制&#8221;字符串中用连续两个%表示，如:<br>printf("%f%%", 1.0/3);<br>输出0.333333%。<br><br>－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br>对于单精度数，使用%f格式符输出时，仅前7位是有效数字，小数6位．<br>对于双精度数，使用%lf格式符输出时，前16位是有效数字，小数6位．</font></p>
<p><font color=#0000ff>&nbsp;</font></p>
<p><font color=#0000ff>&nbsp;</font></p>
<p><br><font color=#0000ff>由高手指点<br>对于m.n的格式还可以用如下方法表示（例）<br>char&nbsp;ch[20];<br>printf("%*.*s\n",m,n,ch);<br>前边的*定义的是总的宽度，后边的定义的是输出的个数。分别对应外面的参数m和n 。我想这种方法的好处是可以在语句之外对参数m和n赋值，从而控制输出格式。 </font></p>
<p><font color=#0000ff></font>&nbsp;</p>
<p><font color=#0000ff>一种输出格式 %n 可以将所输出字符串的长度值赋绐一个变量, 见下例:<br><br>int slen;<br><br>printf("hello world%n", &amp;slen);<br><br>执行后变量被赋值为11</font><br><br><br><br><br>scanf格式控制的完整格式：<br>%&nbsp; *&nbsp; m&nbsp; l或h&nbsp; 格式字符<br>①格式字符与printf函数中的使用方式相同，以%d、%o、%x、%c、%s、%f、%e，无%u格式、%g格式。<br>②可以指定输入数据所占列宽，系统自动按它截取所需数据。如:<br>scanf(&#8220;%3d%3d&#8221;,&amp;a,&amp;b);<br>输入：123456<br>系统自动将123赋给a,456赋给b。<br>③%后的&#8220;*&#8221;附加说明符，用来表示跳过它相应的数据。例如：<br>scanf(&#8220;%2d%*3d%2d&#8221;,&amp;a,&amp;b);<br>如果输入如下信息：1234567。将12赋给a，67赋给b。第二个数据&#8221;345&#8221;被跳过不赋给任何变量。<br>④输入数据时不能规定精度，例如：<br>scanf(&#8220;%7.2f&#8221;,&amp;a);<br>是不合法的，不能企图输入：12345.67而使a的值为12345.67。<br><br>－－－－－－－－－－－－－－－－－－相关－－－－－－－－－－－－－－－－－－－<br>输入数据流分隔<br>①根据格式字符的含义从输入流中取得数据，当输入流中数据类型与格式字符要求不符时，就认为这一项结束。如：<br>scanf(&#8220;%d%c%f&#8221;,&amp;a,&amp;b,&amp;c)；<br>如果输入如下信息：<br>1234r1234.567<br>则scanf函数在接收数据时发现&#8221;r&#8221;类型不匹配，于是把&#8221;1234&#8221;转换成整型赋值给a，把&#8221;r&#8221;赋给变量b，最后把&#8221;1234.567&#8221;转换成实型数据赋给c。<br>②根据格式项中指定的域宽分隔出数据项。如语句：scanf(&#8220;%2d%3f%4f&#8221;,&amp;a,&amp;b,&amp;c);<br>如果输入如下信息：<br>123456789012345<br>&nbsp;&nbsp; 则scanf函数在接收数据时根据域宽把12赋值给a,345赋值给b，6789赋值给c。<br>③隐示分隔符。空格、跳格符（&#8217;\t&#8217;）、换行符（&#8217;\n&#8217;）都是C语言认定的数据分隔符。<br>④显示分隔符。在scanf函数的两个格式说明项间有一个或多个普通字符，那么在输入数据时，在两个数据之间也必须以这一个或多个字符分隔。如语句：<br>scanf(&#8220;a=%d,b=%f,c=%f&#8221;,&amp;a,&amp;b,&amp;c);<br>则输入数据应该为：<br>&nbsp;&nbsp; a=1234,b=67.8,c=98.123<br><br>－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br>关于scanf函数的进一步说明：<br>①scanf函数中的&#8220;格式控制&#8221;后面应当是变量地址，而不应是变量名。例如，如果a、b为整型变量，则<br>scanf(&#8220;%d,%d&#8221;,a,b);<br>是不对的，应将&#8221;a，b&#8221;改为&#8221;&amp;a,&amp;b&#8221;。<br>②如果在&#8220;格式控制&#8221;字符串中除了格式说明以外还有其它字符，则在输入数据时应输入与这些字符相同的字符。例如：<br>scanf(&#8220;%d,%d&#8221;,&amp;a,&amp;b);<br>输入时应输入：3，4。3与4之间的逗号应与scanf函数中的&#8220;格式控制&#8221;中的逗号相对应，输入其它符号是不对的。<br>③在用&#8220;%c&#8221;格式输入字符时，空格字符和转义字符都作为有效字符输入。<br>scanf(&#8220;%c%c%c&#8221;,&amp;c1,&amp;c2,&amp;c3);<br>如输入：a b c 。字符&#8217;a&#8217;赋给c1,字符（空格）&#8217; &#8217;赋给c2,字符&#8217;b&#8217; 赋给c3。<br>④ scanf&nbsp; 中不使用U说明符.对unsigned型数据用d、o、x说明符输入.</p>
<img src ="http://www.cppblog.com/xinxin/aggbug/98891.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xinxin/" target="_blank">勇敢空心人</a> 2009-10-18 18:38 <a href="http://www.cppblog.com/xinxin/archive/2009/10/18/98891.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>