﻿<?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/tx7do/category/1486.html</link><description>危机感是一种强大前进的动力！&lt;/br&gt;
GMail/GTalk: yanglinbo#google.com;&lt;/br&gt;
MSN/Email: tx7do#yahoo.com.cn;&lt;/br&gt;
QQ: 3 0 3 3 9 6 9 2 0 .</description><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 13:03:59 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 13:03:59 GMT</pubDate><ttl>60</ttl><item><title>华容道系列</title><link>http://www.cppblog.com/tx7do/archive/2006/09/18/12691.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Mon, 18 Sep 2006 13:41:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/09/18/12691.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/12691.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/09/18/12691.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/12691.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/12691.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 作者:吕震宇来源:http://www.cnblogs.com/zhenyulu						华容道系列－开篇												一、 序言		这个学期给学生上《设计模式》的课程，有些学生提出找些题目练练手，增强一些实战经验，我决定让他们编写"华容道"游戏。说实在的，当时并没有深思熟虑。后来自己仔细想想，发现这里面东西还真不少，甚至包括下学期我才给他们开设的课程《数据...&nbsp;&nbsp;<a href='http://www.cppblog.com/tx7do/archive/2006/09/18/12691.html'>阅读全文</a><img src ="http://www.cppblog.com/tx7do/aggbug/12691.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-09-18 21:41 <a href="http://www.cppblog.com/tx7do/archive/2006/09/18/12691.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STL实现哈夫曼算法</title><link>http://www.cppblog.com/tx7do/archive/2006/07/07/9521.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Fri, 07 Jul 2006 03:59:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/07/07/9521.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/9521.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/07/07/9521.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/9521.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/9521.html</trackback:ping><description><![CDATA[近日在做STL编程, 这篇文章帖出来共享 <br /><br /><br />用C++ std::priority_queue　实现哈夫曼算法我想每个计算机专业的学生或多或少都接触过哈夫曼编码，数据结构中的老问题了。大体就是给出一些字符，和这些字符的出现频率，让你为这些字符设计一个二进制编码，要求频率最高的字符的编码最短。解决的方法是构造一棵哈夫曼树（二叉树），其基本思路是，每次从这些字符中挑出两个频率最低的，然后构造一个新的结点，使新结点的左右孩子指针分别指向那两个节点。我想这个大家都很清楚了，我就不多说了。主要讲下这次我用C++实现时遇到的问题。首先，我定义了一个哈夫曼树结点： <br /><br />class hNode <br />{ <br />public: <br />friend bool operator &gt; (hNode n1,hNode n2);　//定义了大于符号，供优先队列排列使用 <br />hNode(string d="",int i=0,hNode* l = NULL,hNode* r =NULL):left(l),right(r),data(d),value(i){} <br />hNode* left; <br />hNode* right; <br />string data; //储存的字符串 <br />int value; //字符串出现的次数 <br />}; <br /><br />bool operator &gt;(hNode n1,hNode n2) <br />{ <br />return n1.value &gt; n2.value; <br />} <br />因为只是算法课的小作业，所以我也不准备为hNode定义完整的二叉树操作，仅仅只是存放数据的对象，所以只有一个构造函数，并且所有的data member都是公有的。 <br /><br />这此写这个算法会遇到大麻烦，主要因为是用了std::priority_queue容器。当时考虑到在哈夫曼中要每次挑选两个频率最小（即出现次数最小，我那个hNode里的value是出现的次数），很自然的就想到了std::priority_queue容器，优先队列每次都会弹出队列中权值最高的元素，这个特性无疑是实现哈夫曼算法的最佳选择。然而因为第一次用std::priority_queue容器，结果出了不少问题，好在最后都一一解决，也学到了不少东西。 <br /><br />初步的设想是这样的，先把所有的hNode对象都压入优先队列中去，然后每次弹出两个，组成一个新的结点，再把新的结点压入队列，重复这一步骤，当队列中只有一个元素时，哈夫曼树也就完成了。像这样：（是错的，可别学） <br /><br />while(...) <br />{ <br />std::priority_queue&lt;hNode&gt; q; <br />..... <br />hNode h1 = q.top(); <br />q.pop(); <br />hNode h2 = q.top(); <br />q.pop(); <br />hNode r; <br />r.left = h1; <br />r.right = h2; <br />r.value = h1.value + h2.value; <br />q.push(r); <br />} <br /><br />然而遭遇的第一个问题是，STL的所有容器的的插入都是基于by value语义的，也就是要生成一个对象的副本放在容器中。这样的后果就是hNode的left,right指针都指到不知道什么地方去了。大家可以稍微画几个图试一下，就知道出了什么问题了。考虑一下后，发现如果队列里存放hNode的指针，就不会出现这个问题了，于是改写成： <br /><br /><br />然而马上遭遇了第二个问题。std::priority_queue在判断优先关系的时候，直接比较指针的地址，而不是指针指向的对象的大小关系。而指针不是类，我没办法重写指针的比较操作。程序陷入了困境之中。std::priority_queue默认使用Greater&lt;&gt;模板来生成一个function object来对元素进行比较，我试图为Greater&lt;&gt;写一个hNode*的特化版本来改变优先队列对hNode*的比较，然而也没有成功。山重水复疑无路之时，突然想到为什么不直接为优先队列写一个function object来替代Greater&lt;&gt;不就可以了吗？赶快写下如下代码： <br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000"> phNodeComp <br /><img id="Codehighlighter1_19_129_Open_Image" onclick="this.style.display='none'; Codehighlighter1_19_129_Open_Text.style.display='none'; Codehighlighter1_19_129_Closed_Image.style.display='inline'; Codehighlighter1_19_129_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_19_129_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_19_129_Closed_Text.style.display='none'; Codehighlighter1_19_129_Open_Image.style.display='inline'; Codehighlighter1_19_129_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_19_129_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_19_129_Open_Text"><span style="COLOR: #000000">{ <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000"> () (</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> hNode</span><span style="COLOR: #000000">*&amp;</span><span style="COLOR: #000000"> left,</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> hNode</span><span style="COLOR: #000000">*&amp;</span><span style="COLOR: #000000"> right) </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> <br /><img id="Codehighlighter1_87_126_Open_Image" onclick="this.style.display='none'; Codehighlighter1_87_126_Open_Text.style.display='none'; Codehighlighter1_87_126_Closed_Image.style.display='inline'; Codehighlighter1_87_126_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_87_126_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_87_126_Closed_Text.style.display='none'; Codehighlighter1_87_126_Open_Image.style.display='inline'; Codehighlighter1_87_126_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span><span id="Codehighlighter1_87_126_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_87_126_Open_Text"><span style="COLOR: #000000">{ <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> left</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">value </span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> right</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">value; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">; </span></div><br /><br />然后把std::priority_queue的申明变为： <br />priority_queue&lt;hNode*,vector&lt;hNode*&gt;,phNodeComp &gt; pq; <br /><br />终于把这个问题给解决了。看样子仅从书本上获得的知识是不牢靠的，一定要自己实践了才会有真正的认识。 <br /><br />posted on 2004-03-19 19:47 Justin Shen 评论(6) 编辑 收藏 <br /><br />Comments <br /># re: 用C++ std::priority_queue　实现哈夫曼算法 <br />earthharp <br />只有成树 <br />没有编码解码吗？ <br />我觉得用BucketSort还要优秀一些 <br />注意你的空间是否正确回收 <br />Posted @ 2004-03-20 01:06 <br /># re: 用C++ std::priority_queue　实现哈夫曼算法 <br />Justin Shen <br />目前只做到把每个字符的编码打印出来，因为老师只要求到这点，实际做哈夫曼编码还是会有一点问题。空间回收在遍历哈夫曼树的过程中一起完成了。 <br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">vector</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> v; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> DoPrint(hNode</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> r) <br /><img id="Codehighlighter1_40_339_Open_Image" onclick="this.style.display='none'; Codehighlighter1_40_339_Open_Text.style.display='none'; Codehighlighter1_40_339_Closed_Image.style.display='inline'; Codehighlighter1_40_339_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_40_339_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_40_339_Closed_Text.style.display='none'; Codehighlighter1_40_339_Open_Image.style.display='inline'; Codehighlighter1_40_339_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_40_339_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_40_339_Open_Text"><span style="COLOR: #000000">{ <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (r</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">left </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">NULL </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> r</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">right </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> NULL) <br /><img id="Codehighlighter1_84_207_Open_Image" onclick="this.style.display='none'; Codehighlighter1_84_207_Open_Text.style.display='none'; Codehighlighter1_84_207_Closed_Image.style.display='inline'; Codehighlighter1_84_207_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_84_207_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_84_207_Closed_Text.style.display='none'; Codehighlighter1_84_207_Open_Image.style.display='inline'; Codehighlighter1_84_207_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span><span id="Codehighlighter1_84_207_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_84_207_Open_Text"><span style="COLOR: #000000">{ <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> r</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">data </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">; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></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"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">v.size();</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i) <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> v; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> endl; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />v.pop_back(); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />delete r; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> ; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (r</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">left) <br /><img id="Codehighlighter1_224_263_Open_Image" onclick="this.style.display='none'; Codehighlighter1_224_263_Open_Text.style.display='none'; Codehighlighter1_224_263_Closed_Image.style.display='inline'; Codehighlighter1_224_263_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_224_263_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_224_263_Closed_Text.style.display='none'; Codehighlighter1_224_263_Open_Image.style.display='inline'; Codehighlighter1_224_263_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span><span id="Codehighlighter1_224_263_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_224_263_Open_Text"><span style="COLOR: #000000">{ <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />v.push_back(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />DoPrint(r</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">left); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (r</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">right) <br /><img id="Codehighlighter1_281_321_Open_Image" onclick="this.style.display='none'; Codehighlighter1_281_321_Open_Text.style.display='none'; Codehighlighter1_281_321_Closed_Image.style.display='inline'; Codehighlighter1_281_321_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_281_321_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_281_321_Closed_Text.style.display='none'; Codehighlighter1_281_321_Open_Image.style.display='inline'; Codehighlighter1_281_321_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span><span id="Codehighlighter1_281_321_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_281_321_Open_Text"><span style="COLOR: #000000">{ <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />v.push_back(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />DoPrint(r</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">right); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />v.pop_back(); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"> </span></div><br />Posted @ 2004-03-20 11:10 <br /># re: 用C++ std::priority_queue　实现哈夫曼算法 <br />代其锋 <br />我的qq94381334 <br />Posted @ 2004-04-08 19:17 <br /># re: 用C++ std::priority_queue　实现哈夫曼算法 <br />simon <br />thx <br />Posted @ 2004-04-29 19:59 <br /># re: 用C++ std::priority_queue　实现哈夫曼算法 <br />yijian <br />译码也不难嘛，只需输入二进制字符就可了，然后判断是0还是1，是 <br />1就在右子树找，顺次下去，0在左找，最后判断是否结点有左右子树 <br />，没有则打印信息。回到头结点，for语句循环即可 <br />Posted @ 2004-05-30 17:43 <br /># re: 用C++ std::priority_queue　实现哈夫曼算法 <br />代其锋（yijian） <br />译码也不难嘛，只需输入二进制字符就可了，然后判断是0还是1，是 <br />1就在右子树找，顺次下去，0在左找，最后判断是否结点有左右子树 <br />，没有则打印信息。回到头结点，for语句循环即可 <img src ="http://www.cppblog.com/tx7do/aggbug/9521.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-07-07 11:59 <a href="http://www.cppblog.com/tx7do/archive/2006/07/07/9521.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>梅森素数--美丽的贝壳</title><link>http://www.cppblog.com/tx7do/archive/2006/04/20/5965.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Thu, 20 Apr 2006 09:47:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/04/20/5965.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/5965.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/04/20/5965.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/5965.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/5965.html</trackback:ping><description><![CDATA[
		<font size="2">一、价值五万美元的素数<br /><br />   2000年4月6日，住在美国密歇根州普利茅茨的那扬·哈吉拉特瓦<br />拉(Nayan Hajratwala)先生得到了一笔五万美元的数学奖金，因为他<br />找到了迄今为止已知的最大素数，这是一个梅森素数：<br />                    2^6972593-1。<br />这也是我们知道的第一个位数超过一百万位的素数。精确地讲，如果<br />把这个素数写成我们熟悉的十进制形式的话，它共有两百零九万八千<br />九百六十位数字，如果把它以这个形式写下来，大约需要150到200篇<br />本文的篇幅。<br /><br />   可是哈吉拉特瓦拉先生并不是一个数学家，他甚至很可能对寻找<br />素数的数学理论一无所知——虽然这使他赢得了这笔奖金。他所做的<br />一切，就是从互联网上下载了一个程序。这个程序在他不使用他的奔<br />腾II350型计算机时悄悄地运行。在经过111天的计算后，上面所说的<br />这个素数被发现了。<br /><br /><br />二、梅森素数<br /><br />   我们把一个大于1的自然数叫作素数，如果只有1和它本身可以整<br />除它。如果一个比1大的自然数不是素数，我们就叫它合数。1既不是<br />素数，也不是合数。<br /><br />   比如说，你很容易就可以验证7是一个素数；而15是一个合数，因<br />为除了1和15外，3和5都可以整除15。根据定义，2是一个素数，它是<br />唯一的偶素数。早在公元前三百年的古希腊时代，伟大的数学家欧几<br />里德就证明了存在着无穷多个素数。<br /><br />   关于素数，有许多既简单又美丽，但是极为困难的，到现在还没<br />有答案的问题。其中有著名的哥德巴赫猜想，它是说任何一个大于6的<br />偶数，都能表示为两个奇素数之和。还有孪生素数问题。象5和7，41<br />和43这样相差2的素数对，被称为孪生素数。孪生素数问题是说：是不<br />是有无穷多对孪生素数？这里要顺便提一下的是，这些看起来很简单<br />的数学问题，它们的解决方法将一定是极其复杂的，需要最先进的数<br />学工具。如果你不是狂妄到认为几百甚至几千年来所有在这些问题上<br />耗费了无数聪明才智的数学家（有许多是非常伟大的）和数学爱好者<br />加起来都不如你聪明，就不要试图用初等方法去解决这些问题，徒费<br />时间和精力。<br /><br />   古希腊人还对另一种数感兴趣。他们将它称为<span style="COLOR: rgb(255,0,0)">完美数</span>。一个大于1<br />的自然数叫完美数，如果它的所有因子（包括1，但不包括本身）之和<br />等于它本身。比如说6=1+2+3就是最小的完美数，古希腊人把它看作维<br />纳斯也就是爱情的象征。28=1+2+4+7+14是另一个完美数。欧几里德证<br />明了：一个偶数是完美数，当且仅当它具有如下形式：<br />                   2^(p-1)(2^p-1)<br />其中2^p-1是素数。上面的6和28对应着p=2和3的情况。我们只要找到<br />了一个形如2^p-1的素数，也就知道了一个偶完美数；我们只要找到所<br />有形如2^p-1的素数，也就找到了所有偶完美数。所以哈吉拉特瓦拉先<br />生不但找到了世界上已知的最大的素数，还找到了世界上已知的最大<br />的偶完美数。嗯，你要问，关于奇完美数又是怎么样的情况？回答是：<br />我们现在连一个奇完美数也没有找到过，我们甚至根本不知道是不是<br />有奇完美数存在。我们只知道，要是有奇完美数存在的话，它一定是<br />非常非常大的！奇完美数是否存在这个问题，也是一个上面所说的既<br />简单又美丽，但是极为困难的著名数学问题。<br /><br />   有很长一段时间人们以为对于所有素数p，<br />                       M_p=2^p-1  <br />都是素数（注意到要使2^p-1是一个素数，p本身必须是一个素数，想<br />一想为什么？）但是在1536年雷吉乌斯(Hudalricus Regius)指出，<br />M_11=2^11-1=2047=23*89不是素数。<br /><br />   皮特罗·卡塔尔迪(Pietro Cataldi)首先对这类数进行了系统的<br />研究。他在1603年宣布的结果中说，对于p=17，19，23，29，31和37，<br />2^p-1是素数。但是1640年费尔马使用著名的费尔马小定理（不要和那<br />个费尔马大定理混淆起来）证明了卡塔尔迪关于p=23和37的结果是错<br />误的，欧拉在1738年证明了p=29的结果也是错的，过后他又证明了关<br />于p=31的结论是正确的。值得指出的是，卡塔尔迪是用手工一个一个<br />验算取得他的结论的；而费尔马和欧拉则是使用了在他们那时最先进<br />的数学知识，避免了许多复杂的计算和因此可能造成的错误。<br /><br />   法国神父梅森(Marin Mersenne)在1644年他发表了他的成果。他<br />宣称对于p=2，3，5，7，13，17，19，31，67，127和257，2^p-1都是<br />素数，而对于其它小于257的素数p，2^p-1都是合数。今天我们把形如<br />M_p=2^p-1的素数叫做<span style="COLOR: rgb(255,0,0)">梅森素数</span>，M_p中的M就是梅森姓氏的第一个字母。<br /><br />   用手工来判断一个很大的数是否素数是相当困难的，梅森神父自<br />己也承认他的计算并不一定准确。一直要等到一个世纪以后，在1750<br />年，欧拉宣布说找到了梅森神父的错误：M_41和M_47也是素数。可是<br />伟大如欧拉也会犯计算错误——事实上M_41和M_47都不是素数。不过<br />这可不是说梅森神父的结果就是对的。要等到1883年，也就是梅森神<br />父的结果宣布了两百多年后，第一个错误才被发现：M_61是一个素数。<br />然后其它四个错误也被找了出来：M_67和M_257不是素数，而M_89和<br />M_107是素数。直到1947年，对于p&lt;=257的梅森素数M_p的正确结果才<br />被确定，也就是当p=2，3，5，7，13，17，19，31，61，89，107和<br />127时，M_p是素数。现在这个表已经被反复验证，一定不会有错误了。<br /><br />   下面是我们现在知道的所有梅森素数的列表：（我们注意到梅森<br />神父的名字不在上面——这种素数已经由他的名字命名了，就把荣誉<br />分给最后确认者吧。）<br /><br />序号   p           M_p的位数    相对应的   确认      确认人<br />                                  完美数的   年代<br />                                    位数<br />1            2            1            1      ----      ---- <br />2            3            1            2      ----      ---- <br />3            5            2            3      ----      ---- <br />4            7            3            4      ----      ---- <br />5           13            4            8      1456      佚名<br />6           17            6           10      1588      Cataldi <br />7           19            6           12      1588      Cataldi <br />8           31           10           19      1772      Euler <br />9           61           19           37      1883      Pervushin <br />10          89           27           54      1911      Powers <br />11         107           33           65      1914      Powers <br />12         127           39           77      1876      Lucas <br />13         521          157          314      1952      Robinson <br />14         607          183          366      1952      Robinson <br />15        1279          386          770      1952      Robinson <br />16        2203          664         1327      1952      Robinson <br />17        2281          687         1373      1952      Robinson <br />18        3217          969         1937      1957      Riesel <br />19        4253         1281         2561      1961      Hurwitz <br />20        4423         1332         2663      1961      Hurwitz <br />21        9689         2917         5834      1963      Gillies <br />22        9941         2993         5985      1963      Gillies <br />23        11213        3376         6751      1963      Gillies <br />24        19937        6002        12003      1971      Tuckerman<br />25        21701        6533        13066      1978      Noll &amp; Nickel <br />26        23209        6987        13973      1979      Noll<br />27        44497       13395        26790      1979      Nelson &amp; Slowinski <br />28        86243       25962        51924      1982      Slowinski <br />29       110503       33265        66530      1988      Colquitt &amp; Welsh<br />30       132049       39751        79502      1983      Slowinski <br />31       216091       65050       130100      1985      Slowinski <br />32       756839      227832       455663      1992      Slowinski &amp; Gage <br />33       859433      258716       517430      1994      Slowinski &amp; Gage <br />34      1257787      378632       757263      1996      Slowinski &amp; Gage <br />35      1398269      420921       841842      1996      GIMPS<br />36      2976221      895932      1791864      1997      GIMPS<br />37      3021377      909526      1819050      1998      GIMPS <br />38     6972593     2098960      4197919      1999      GIMPS<br />39    13466917   4053947<br />40 　 20996011  6320431<br />41    24036583  7235734<br />42     25964951   7816230                           2005<br /><br />   是不是有无穷多个梅森素数呢？数学家们目前还无法回答这个问<br />题。<br /><br /><br />三、寻找更大的素数<br /><br />   为什么要寻找梅森素数？为什么要打破已知最大素数的纪录？这<br />有什么用处呢？<br /><br />   如果你所说的用处是指能够直接创造物质财富，那么我不得不告<br />诉你——梅森素数没有什么用处，多知道一个非常大的素数似乎也没<br />什么用处。即使我们知道了一个无比巨大的梅森素数，也不会使我们<br />的钱包增加一分钱（嗨等一等！如果你只对钱感兴趣的话，也请不要<br />立刻撇下我的文章。我其实是说，我上面说的话要排除我在这篇文章<br />题目中提到的那十万美元的奖金——你的钱包也许会因此鼓起来的。<br />所以请耐心一点）。<br /><br />   但是人类并不只需要物质财富。博物馆里的钻石有什么用场呢？<br />为什么人类要收集它们？因为它们美丽而稀少。作为人类智慧的结晶，<br />素数、梅森素数和与它密切相关的完美数是非常美丽的。它们的定义<br />简单，却又如此神秘莫测，象欧几里德、笛卡尔、费尔马、莱布尼兹、<br />欧拉这样的伟大数学家都因为它们的美丽而对它作过大量研究；大家<br />也看到，两千多年来，经过无数代人的辛勤工作，我们一共只收集到<br />38个梅森素数，它们是非常稀少的。对于数学家来说，搜集素数、梅<br />森素数和完美数是和收集钻石一样富有乐趣的事情。<br /><br />   人类还需要荣耀——也许更胜于财富。在体育运动中，能够跑得<br />更快一点，跳得更高一点，难道真的有实际物质方面的用途吗？不，<br />我们喜欢接受挑战，我们希望能赢。打破一个体育世界记录，攀登珠<br />穆朗玛峰，单身驾船横穿太平洋……，那是对人类体能极限的挑战；而寻<br />找更大的素数，则是一项对人类智慧的挑战。当我们完成了一项前所<br />未有的任务时，我们总会感到无比骄傲。1963年，当第23个梅森素数<br />被找到时，发现它的美国伊利诺斯大学数学系是如此地骄傲，以致于<br />把所有从系里发出的信件都敲上了“2^11213-1是个素数”的邮戳。<br /><br />   在欧拉证明M_31是素数以后，下一个最大素数的记录由兰德里<br />(Landry)于1867年获得：M_59/179951=3203431780337。这不是一个梅<br />森素数。这个记录保持了九年。<br /><br />   1876年爱德华·卢卡斯使用了一个比费尔马和欧拉的方法更先进<br />的手段，证明了M_127是一个素数。这个记录保持了七十五年。直到费<br />里叶(Ferrier)于1951年使用一部手摇计算机证明了(2^148+1)/17是一<br />个素数，它有41位数。<br /><br />   借助手摇计算机的方法要算作手工计算方法还是要算做计算机方<br />法，大概是可以探讨的问题。不过技术的发展一下子把这种争论变得<br />毫无必要。值得指出的是，在人类寻找大素数的旅途中，数学理论的<br />改善要远远比具有强大坚韧的计算能力重要得多。卢卡斯的方法在<br />1930年被勒梅(Lehmer)简化后，卢卡斯-勒梅测试成为现在寻找梅森素<br />数的标准方法。<br /><br />（卢卡斯-勒梅测试：对于所有大于1的奇数p，M_p是素数当且仅当M_p<br />整除S(p-1)，其中S(n)由S(n+1)=S(n)^2-2，S(1)=4递归定义。<br />4  14 194  37634  1416317954 2005956546822746114<br />这个测<br />试尤其适合于计算机运算，因为除以M_p=2^p-1的运算在二进制下可以<br />简单地用计算机特别擅长的移位和加法操作来实现。判断一个梅森数<br />是素数的方法比判断一个差不多大小的其他类型数是素数的方法要简<br />单得多，所以在寻找最大素数的过程中，大部分纪录都是梅森素数。）<br /><br />   在1951年米勒和维勒(Miller &amp; Wheeler)借助于EDSAC计算机（这<br />种计算机还不如我们现在使用的一般计算器，它只有5K的内存）发现<br />了长达79位的素数180(M_127)^2+1。这个记录还是没能保持多久。次<br />年罗宾逊应用SWAC计算机，在1952年初发现了第13和第14号梅森素数：<br />M_521和M_607，后面连续三个梅森素数也在同一年被陆续发现：M_1279，<br />M_2203和M_2281。<br /><br />   在那以后的年代里，为了打破巨大素数纪录而使用的计算机越来<br />越强大，其中有著名的IBM360型计算机，和超级计算机Cray系列。大<br />家可以参看上面的梅森素数表来了解这个竞赛过程。在此其间只有一<br />次一个不是梅森素数的素数坐上过“已知最大素数”的宝座，它是<br />39158*2^216193-1，在1989年被发现。1996年发现的M_1257787是迄今<br />为止最后一个由超级计算机发现的梅森素数，数学家使用了Cray T94。<br /><br />   然后，GIMPS的时代到来了。<br /><br /><br />四、GIMPS——互联网梅森素数大搜索<br /><br />   1995年程序设计师乔治·沃特曼(George Woltman)开始收集整理<br />有关梅森素数计算的数据。他编制了一个梅森素数寻找程序并把它放<br />在网页上供数学爱好者免费使用。这就是“互联网梅森素数大搜索”<br />计划(GIMPS，the Great Internet Mersenne Prime Search)。在这个<br />计划中，十几位数学专家和几千名数学爱好者正在寻找下一个最大的<br />梅森素数，并且检查以前梅森素数纪录之间未被探索的空隙。比如上<br />面的梅森素数表中，最后那个素数的序号是未知的，我们不知道第37<br />号梅森素数和它之间是否还存在着其他未被发现的梅森素数。<br /><br />1997年斯科特·库尔沃斯基(Scott Kurowski)和其他人建立了“素数<br />网”(PrimeNet)，使分配搜索区间和向GIMPS发送报告自动化。现在只<br />要你去GIMPS的主页下载那个免费程序，你就可以立刻参加GIMPS计划<br />搜寻梅森素数。几乎所有的常用计算机平台都有可用的版本。程序以<br />最低的优先度在你的计算机上运行，所以对你平时正常地使用计算机<br />几乎没有影响。程序也可以随时被停止，下一次启动时它将从停止的<br />地方继续进行计算。<br /><br />   从1996年到1998年，GIMPS计划发现了三个梅森素数：M_1398269、<br />M_2976221和M_3021377，都是使用奔腾型计算机得到的结果。<br /><br />   1999年3月，在互联网上活动的一个协会“电子边界基金”(EFF，<br />Electronic Frontier Foundation)宣布了由一位匿名者资助的为寻找<br />巨大素数而设立的奖金。它规定向第一个找到超过一百万位的素数的<br />个人或机构颁发五万美元的奖金，这就是我们最一开始说到的哈吉拉<br />特瓦拉得到的奖金。后面的奖金依次为：超过一千万位，十万美元；<br />超过一亿位，十五万美元；超过十亿位，二十五万美元。<br /><br />   搜寻结果的验证和奖金的颁发是非常严格的。比如说，得到的结<br />果必须是显式的——你不能宣称你的结果是一个有一百个方程组成的<br />方程组的解，却不把它解出来。结果必须由另一台计算机独立验证。<br />所有这些规则都在EFF网站上进行了解释。<br /><br />   应该指出的是，通过参加GIMPS计划来获得奖金的希望是相当小的。<br />哈吉拉特瓦拉使用的计算机是当时21000台计算机中的一台。每一个参<br />与者都在验证分配给他的不同梅森数，当然其中绝大多数都不是素数<br />——他只有大约三万分之一的可能性碰到一个素数。<br /><br />   下一个十万美元的奖金将被颁发给第一个找到超过一千万位的素<br />数的个人或机构。这一次的计算量将大约相当于上一次的125倍。现在<br />GIMPS得到的计算能力为每秒7000亿次浮点运算，和一台当今最先进的<br />超级矢量计算机，比如Cray T932的运行能力相当。但是如果GIMPS要<br />使用这样的超级计算机，一天就需要支付大约二十万美元。而现在他<br />们需要的费用，仅仅是支持网站运行的费用，和总共几十万美元的<br />奖金罢了。<br /><br /><br />五、网上分布式计算计划<br /><br />   GIMPS只不过是互联网上众多的分布式计算计划中的一个，<br />GIMPS主页上就有这些计划的介绍。<br /><br />   分布式计算是一门计算机学科，它研究如何把一个需要非常巨大<br />的计算能力才能解决的问题分成许多小的部分，然后把这些部分分配<br />给许多计算机进行处理，最后把这些计算结果综合起来得到最终的结<br />果。有时侯计算量是如此之大，需要全世界成千上万甚至更多台计算<br />机一起工作，才能在合乎情理的时间内得到结果。GIMPS计划就是在进<br />行这样的分布式计算。 <br /><br />   但它并不是最著名的分布式计算计划。致力于寻找宇宙中智慧生<br />命的“搜寻地外文明计划”(SETI计划)中的SETI@HOME工程，已在全世<br />界招募了290万名(!)志愿者，利用屏幕保护程序来处理射电望远镜接<br />受到的大量的宇宙间传来的无线电信号。如果你参加这个计划，也许<br />有一天会在你的计算机上破译出外星人发来的问候呢。<br /><br />   你也可以用你的计算机空余的计算能力为人类征服癌症作出贡献。<br />英国科学家设计了类似SETI@HOME工程的分布式计算屏保，它从有关网<br />站下载数据，分析化学物质分子的抗癌性能，然后将分析结果通过互<br />联网传回给研究人员，作为研制新型抗癌药物的参考。这项工程将于<br />2001年4月3日在美国加利福尼亚州正式启动。<br /><br />   计算机硬件的更新令人目不暇接，上半年买的最新式的个人电脑，<br />在下半年就变成了大路货。三四年前的CPU，现在变得一钱不值——<br />也许不能这么说，你根本就买不到它们了——市面上最便宜的CPU也<br />要比它们强大得多。而一台普通的家用计算机连续运转五年也是没有<br />问题的。所以，对待计算机的最经济的态度就是：让它运转。<br /><br />   而人类还有那么多的东西需要计算，还有那么多的问题需要找到<br />回答，还有那么多的难关需要克服。我们需要越来越巨大的计算能力，<br />我们也拥有这样的计算能力，只是太多太多被白白地闲置浪费掉了。<br />互联网已经使大规模的分布式计算计划成为可能。现在，我们唯一需<br />要的，就是这个网每一个结点上计算机用户的意愿和信心了。</font>
<img src ="http://www.cppblog.com/tx7do/aggbug/5965.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-04-20 17:47 <a href="http://www.cppblog.com/tx7do/archive/2006/04/20/5965.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HillTop (LocalScore) 算法 </title><link>http://www.cppblog.com/tx7do/archive/2006/04/17/5783.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Mon, 17 Apr 2006 10:45:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/04/17/5783.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/5783.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/04/17/5783.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/5783.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/5783.html</trackback:ping><description><![CDATA[
		<p>
				<font size="2">HillTop (LocalScore) 算法 <br />作者：Atul Gupta <br />Google新算法的庐山真面目到底是什么？这仍然是个迷。而在Google网站上，从其"对高质量内容网站进行奖励及对采用恶意技术的网站进行惩戒"内容中，亦无什么新内容可寻端倪。自然，作为搜索引擎，这种做法是完全可以理解的。搜索引擎的算法应该是保密的，因为它们对新算法的任何评论，同意或否定的言行都会泄露其新算法，而任何对排名系统的一丁点泄漏都有可能被一些人钻了空子，并用来恶意操纵搜索结果，从而破坏搜索结果的客观公正性。 <br />我们根据一些比较具有可行性的推测，并结合实际研究、试验，以及对搜索引擎行为的发展趋势和历史的知识基础，得出了一些发现。首先，我们来看看对于Google新算法的一些比较值得注目的发现：<br /><br />1.Google新算法种种之种种传言 &amp; 猜测<br /><br />对于Google新算法主要有下面这样一些传言和猜测： <br /><br />开始使用词典对号入座； <br /><br />意图施压使商业站点使用Adwords广告服务； <br /><br />开始使用"基于贝叶斯定理的SPAM过滤系统" ； <br /><br />开始处罚互惠链接，"优化"网页，或"链接文本" ；<br /><br />众多猜测中，"Google意图施压使商业站点使用Adwords广告服务"显然占了上风。许多</font>
				<a href="http://www.seoclub.cn/seo/index.htm" target="_blank">
						<font color="#0000ff" size="2">搜索引擎优化</font>
				</a>
				<font size="2">分析家都认为：Google通过一个保密的过滤系统"黑名单"来对商业网站进行筛选，从而达到上述目的。对此观点我实在不敢苟同。解释如下…<br /><br />1.1 是否若查询条件中包含"商业性关键词"时，Google会对搜索结果进行筛选？<br /><br />因为这次更新中损失最惨重的是一些商业网站，所以有很多</font>
				<a href="http://www.seoclub.cn/seo/index.htm" target="_blank">
						<font color="#0000ff" size="2">搜索引擎优化</font>
				</a>
				<font size="2">专家都认为Google开始对那些含有所谓"商业性关键词"的查询条件所产生的查询结果进行筛选。而从优化专家针对此所做的一些最初的测试结果来看，确实也表明了一些看起来似乎能够证实这种推测的征兆。<br /><br />1.2 Google此举动机何在？<br /><br />如果这是真的，那么Google为什么要这样做？这种推测的后盾在于Google算法更新的时间正好在圣诞购物季节之前，并适逢其IPO上市之际。分析家认为：Google这样做是为了向商业性站点施加压力，如果这些商业网站期盼在一年一度的美国传统的圣诞购物季节得到丰厚赢利的话，就得花钱做AdWords自助广告。免费午餐看来是没有了。还有一些人则认为Google此举旨在为其最终业绩(即基线)涂抹上一点光明的色彩来打动其未来投资者。<br /><br />1.3 那么又是谁取代了商业站点原来的交椅？<br /><br />从结果页上看，前20个结果好象都是一些官方站点(.gov)，教育类站点(.edu)，公益组织性站点(.org)，目录及非美国本土的站点。由于这些站点一般并不太需要做广告，所以分析家们据此相信：提升这些类型的网站不会影响到Google的广告收入，同时还可以对商业性站点施压并迫使其加入Google的AdWords自助广告阵营中来。<br /><br />1.4 Google从何获得"商业性关键词"名单？<br /><br />从Google的AdWords广告系统，Google已然拥有一个大型的"商业性关键词"的数据库。有趣的是，等于是那些广告客户和商业性站点的所有者自己把哪些是"好的商业词语"告诉给Google了-Google通过广告者对关键词语的竞标价格的变化完全可以看出每个关键词语的"价值"来。<br /><br />1.5 事实究竟如何？Google是否确是在用"商业关键词"名单来过滤掉商业站点？<br /><br />我个人认为：这种想法实在与事实太过相悖，而且我坚信：Google并不象分析家们所认为的在"过滤"站点。而且我相信，Google压根就没有什么"商业关键词"名单。一度流行的这种"过滤名单"理论是分析家们从自己所看到的迹象上得出的，而事实上这些所谓的迹象是由于其它原因所引发的，而并不是什么"过滤"所导致的。后面我会就此问题向大家详细解释和阐述。<br /><br />不可否认，从实践中我们确实可以看到一些象"过滤"的结果，但我们有理由相信这样的结果实际上是Google新算法的一种"副产品"，而非Google本意。新算法意图对商业性网站而不是公益性网站施加影响。稍后我会向大家详细解释…<br /><br />Scroogle.org，这个由不喜欢Google的群体所建立的网站，原来可以通过一种巧妙的方式从Google上提取数据，并向用户提供一种可检查网站在Google上的"未过滤"的往日排名结果的工具。不过由于Google现已更新了算法以禁止此类查询，故Scroogle.org现已无法提供这样的工具。不过，该网站仍显示有一个从其网站上多方搜索而收集到的所谓"Filter Hit"名单。我研究过这个名单。 我觉得，它充其量也只能证明了Google并未使用任何如上所说之名单。不然的确话，如何解释"California Divorce Attorney"位于名单之首而"Books"或"Adult"却屈居最下席？难道在Google眼里，"California Divorce Attorney"比"Books"或"Adult"更有商业价值？<br /><br />Google任何从正常的排名机制中过滤掉把商业性站点的企图都是对Google品牌，乃至对其公正的搜索结果信誉的严重损害。若真有这样的企图，那Google真是太短视了，根本配不上它的品牌和它的服务。Google的股票上市(IPO)和最终业绩都将因此而毁于一旦。此外，Google也说过，其"搜索服务"和"AdWords自助广告"服务分属两个不同的工作部门，且互不搭界、互不影响。对此我还是相信的。<br /><br /><br />2.Google搜索技术的几个明显变化<br /><br />2.1 Google开始采用词干技术(stemming)<br /><br />Google确已在搜索结果中采用了词干技术。在早先，如果搜索一个单数查询条件如"home garden"，则搜索结果中不会出现如"home gardens"，"home gardening"这样的关键词变化形式，反之亦然。对于Google的用户来说，这种特性可能是一件好事情，因为搜索提供的结果更多了，但站在</font>
				<a href="http://www.seoclub.cn/seo/index.htm" target="_blank">
						<font color="#0000ff" size="2">搜索引擎优化</font>
				</a>
				<font size="2">的立场来看，由于搜索结果的骤然增加，对关键词的竞争亦骤然加剧。<br /><br />2.2 Google于搜索结果中使用了拼写纠错工具<br /><br />Google开始将其拼写检查工具用于搜索结果中。例如，当输入查询条件为"Search Engine Optimisation"后，以往Google只会提示你是否是要找"Search Engine Optimization"，但显示的还是符合"Optimisation"的搜索结果。不过现在则能看到"Optimization"的搜索结果。再如："e-mail solution"和"email solution"的搜索结果一致，而"e-commerce"则与"ecommerce"的搜索结果是一致的，这样就增加了数据的竞争性。<br /><br />3.对Hilltop算法的分析和推测<br /><br />3.1 为什么采用新算法<br /><br />大多数网迷们都知道，页面等级算法是由Google的创始人Sergey Brin和Larry Page所倡起的,用以精良网站在搜索结果中的排名。这也是自1998年Google发布以来的取得种种骄人成绩的重要因素之一。 <br /><br />但页面等级系统亦存在着一个基本的缺陷，Google也深知这一点。它根据一个网页上被链接的站点数量和质量来给该网页分配一个绝对的"重要性值"。同时亦将链接页面的页面等级考虑在内。指向一个网页的外部链接页的页面等级越高，则该链接页面传递给该网页的页面等级值也就越高。但是，"页面等级值"并非针对查询词语，因而一个网页即使只是在内容中偶然提到了一个和查询主题偏离的关键词语，也会因其居高的页面等级值而获得一个比较高的排名。<br /><br />美国加州的克利须那。伯哈拉特(Krishna Bharat) 意识到基于页面等级的排名系统中所存在的这种瑕玼，并于2000年提出了一种新算法，他称其为"Hilltop"算法，并于2001年的一月份申请了Hilltop专利权，Google成为受让方。不言而喻，Google已然意识到这种新算法与其页面等级系统的整合将为Google的排名系统带来良好的效果。<br /><br />我深信，在Google最近的更新中，不但运用了Google自身的页面等级和相关性算法，而且还结合使用了Hilltop算法用于精工调整页面等级的效果，只不过Hilltop算法可能已迥异于它最初的模样了。<br /><br />3.2 什么是Hilltop算法？<br /><br />对此算法有兴趣了解并想挖根究底的人可以看看克利须那。伯哈拉特当年所写的Hilltop论文及详细的Hilltop专利信息。但对我们大多数人来说，只要知道Hilltop算法到底是个什么东东就可以了。简单地说，页面等级决定一个网页的"权威性"，而Hilltop(LocalScore)则决定匹配一查询条件的一个网页的"权威性"。<br /><br />Bharat提出：在利用"页面等级"来寻找"权威"网页时，不应单纯依赖于值的大小来定夺，而应将重点放在它与查询主题的相关性上； 即不但需要考虑网页的页面等级，还要考虑该网页的页面等级与查询主题的相关性是否相称。若一个网页只与查询主题只沾点边，那么即使其页面等级非常之高，对用户来说也是没有意义的。如此一来，于网页而言，那些来自于"相关主题"的文档的链接就更有意义了 (Bharat称这种"相关主题"文档为"专家文档")，一个网页的所有外部"专家文档"链接构成了该网页的"权威性值"。Hilltop算法的意义在于：相同主题网站之间的链接应比非相关网站的链接具有更高的价值。<br /><br />Hilltop算法以如下方式计算一个网页的"权威值"(这只是极为简单的一个例子)： <br /><br />以该关键词进行一次普通查询找专家文档"文集"。"专家文档"的定义有严格标准，因该"文集"应是数量上易于管理的一组网页。 <br /><br />从返回的专家列表中把成员站点(见下注解*)和镜象站点去掉。 <br /><br />根据所获得的上述专家文档对其投票的数量和质量，网页被分配以一个“局部分数”(LocalScore)。然后按网页的“局部分数”进行排名。 <br />*注解：成员站点指来自同一个域，或域相同而后缀不同的站点，如ibm.com，ibm.co.uk，ibm.co.jp等等，或指来自相邻的IP地址的站点 (前三位IP地址相同，形如64.129.220.xxx) <br />此外，若两个站点均为相同IP地址下的宿主，则认为其中一个是另外一个站点的成员站点。(即：若ww.abc.com和</font>
				<a href="http://www.ibm.com/" target="_blank">
						<font color="#0000ff" size="2">www.ibm.com</font>
				</a>
				<font size="2">均为相同IP地址下的宿主，则认为</font>
				<a href="http://www.abc.com/" target="_blank">
						<font color="#0000ff" size="2">www.abc.com</font>
				</a>
				<font size="2">是</font>
				<a href="http://www.ibm.co.uk/" target="_blank">
						<font color="#0000ff" size="2">www.ibm.co.uk</font>
				</a>
				<font size="2">的成员站点) <br />Hilltop算法的一个极其重要的特征在于：若没有找到搜索引擎认为数量足够的“专家文件”(要求至少需有两票)，则该算法失效，即返回结果为零。换言之，对于高度明确化的查询条件(查询词语)，Hilltop算法的结果很可能为“0”。这是该算法的一个独特特性。如此一来，造成了</font>
				<a href="http://www.seoclub.cn/seo/index.htm" target="_blank">
						<font color="#0000ff" size="2">SEO</font>
				</a>
				<font size="2">一族中的大部分人都深信Google的确在用“商业词”过滤名单来过滤掉商业网站。<br /><br />事实上，在Hilltop算法无法奏效时，将显示“旧”Google的搜索结果。这些查询条件的集合就是</font>
				<a href="http://www.seoclub.cn/seo/index.htm" target="_blank">
						<font color="#0000ff" size="2">SEO</font>
				</a>
				<font size="2">一族所收集并称之为的“商业词名单”。这一效果无意中却提供了一个强有力的证据，表明Google确是采用了Hilltop算法。2003年11月15号，Google基于新算法的更新之后， 某分析家就指出：在进行查询时，若对某一查询条件加上一些“不包含”的无意义字符，如“car rental – ghjkl”，则Google将会显示以往(算法变化前)的搜索结果，而绕过所谓的“商业词”过滤名单。<br /><br />例如，若查找“real estate –hdfkdhgk”，则Google将试图返回所有关于“real estate”，同时内容中又不包含“hdfkdhgk”的页面。又由于包含“hdfkdhgk” 这种字眼的网页几乎没有，所以按道理来讲，Google返回的查询结果应该和“real estate”的查询结果是相同的。然而结果却出人意料：Google所显示的查询结果和采用新算法之前的搜索结果的排名是相同的。事实上，Scroogle.org这个网站就是捕捉Google的搜索结果在排名上的不同，并以此得出一个所谓的“商业词”过滤名单。<br /><br />在所谓的“商业词”背后到底是什么？<br /><br />我们相信，“商业词”过滤式效果只是Hilltop算法的一个衍生症状。每当用户进行类似“real estate –hdfkdhgk”的查询时，Google都会对整个查询词语进行Hilltop运算，当无法找到足够的包含这种查询词语的“专家文件”时，该算法将返回一个零值(即零效果)。 这就意味着我们通过这种多少有些滑稽的特殊排除词语绕过了Hilltop算法， 这时候Google的其它算法就该出头发挥作用了，而它们所提供的查询结果明显地和算法更新前的查询结果是一样的! 后来Scroogle.org的声名鹊起让Goolge发现了这个bug。后来Google为了防止此类漏洞，索性把查询分成两步走，先把排除条件词语放一边，将查询条件送至Hilltop进行运算，如此一来，由于Hilltop不再同时对排除条件进行解析，所以可保证其正常发挥效用，并提供相应的搜索结果，然后再将此结果传递给Google算法，Google根据最初查询中的排除条件从Hilltop提供的结果中将符合排除条件的网页剔除，然后再将结果显示给用户。这也就是为什么我们现在用上面的法子再也无法看到“旧Google”的搜索结果的原因了。<br /><br />Google新算法意义何在<br /><br />Hilltop算法与Google的页面等级算法及页面相关性算法的结合看起来是超佳组合，几乎无懈可击。其联姻对于链接流行度/页面等级和来自专家文件(LocalScore)的链接对你网站的排名的影响程度有着深远的意义。<br />我列了一个简单的公式来说明新算法的效果和影响 (谨供参考)： <br /><br />“旧”Google排名公式 = {(1-d)+a (RS)} * {(1-e)+b (PR * fb)} <br /><br />“新”Google排名公式 = {(1-d)+a (RS)} * {(1-e)+b (PR * fb)} *{(1-f)+c (LS)}<br />其中： <br /><br />RS = 相关性得分：基于网页标题(Title)。元标识(Meta tags)， 正文标题(Headlines)，正文(Body text)。URL，图片Alt文字，锚文字(Anchor Text)等元素中出现的关键词得出的分数。 <br />PR = 页面等级：(基于链接至你网站的网页数量及其PR值得出的分数。原始公式为PR (A) = (1-d) + d (PR (t1)/C (t1) + …+ PR (tn)/C (tn))，其中D为阻尼因子，一般设为0.85; 公式可描述为：A网页的其PR值等于链向该页面的所有链接页面的PR值分别除以各自的外部链接数量的总和。 <br />LS = 行业得分(LocalScore)：根据专家文件计算得出的分数。 <br /><br />a，b，c = 调节控制比重：Google用于精工调整查询结果 <br /><br />d，e，f = 阻尼控制：Google用于精工调整查询结果。目前“f”值可能为“0”。 <br /><br />fb = 因子基数：Google工具栏山所显示的页面等级得分范围从1到10，但它实质上并不是一个线性函数，而是一个指数/对数函数。经过分析，我们认为它有一个趋近于8的基数。即PR为5的网页的值比PR为4要多8倍之多(PR5=PR4X8)，同样，一个PR值为8的网站比一个PR值为4的网站的值要高出4000多倍(PR8=PR4X8X8X8X8)。<br /><br />Google新算法的优势/优点<br /><br />页面因子极易被人利用和控制，例如最早被用作排名因子的META TAGS，就由于很多网站无度的关键词充斥泛滥而不得不被搜索引擎喊停。此外，在开始的时候，由于顾忌到真实来访者的感受，对网站内容一般作手脚的并不多，但后来亦难免诱惑，过度优化，甚至页面上放上许多“隐形”的内容已是屡见不鲜的伎俩。页面因子确实无形中赋予网站管理员太多“恶意”控制权。而在Google的新算法中，各排名因素所占比重分别如下：<br /><br />总“排名”得分由三部分组成：相关性得分(页面因素)，页面等级得分(非页面因素)和行业得分(非页面因素)：<br />相关性得分(RS)= 20%，页面等级值(PR) = 40%，行业得分(LS) = 40% <br />其中： <br /><br />RS (相关性得分：页面相关度) --是所有</font>
				<a href="http://www.seoclub.cn/seo/index.htm" target="_blank">
						<font color="#0000ff" size="2">SEO</font>
				</a>
				<font size="2">努力的转换结果； <br /><br />PR (页面等级得分：外部链接度) --是所有建立链接的努力的转换结果； <br /><br />LS (行业得分：专家文件链接度) --是得自专家文件的链接的转换结果； <br /><br />从上述结果不难看出，页面优化的得分只占到20%，Google显然已将重心转至非页面因子上，而把排名控制权越来越多地从网站管理员手中夺回来。假若一个水平一般般的优化专家可以拿到RS中的10分，而一个水平很高的优化专家最高也不过能拿到18，19分，大家可以看到：这两个水平悬殊的优化专家之间的差别仅仅只有8分而已! <br /><br />Hilltop算法是否以实时方式运行<br /><br />Google所拥有的服务器体系架构就是网络上分布的一万台奔腾级服务器。而一旦了解了Hilltop算法后，我们很难相信这样的奔腾服务器能够具备如此的处理能力：试想一下，首先要从成千上万的主题性文件中找到“专家文件”，然后计算目标网页自这些专家文件的链接的得分，然后再将数值返回Google算法的其它排名系统，并做进一步处理—而所有这些要在大约0.07秒内--这个让Google举世闻名的搜索速度内完成。确实使人难以置信。<br /><br />Hilltop算法的运行频率及涵盖范围<br /><br />我们认为，要保证Google一贯的“闪电般”搜索速度，Google会对搜索频率较高(热门)的查询词(即所谓的“商业词”黑名单)定期运行批处理，并将结果存储起来供日后使用。Google的数据库拥有数目庞大的高查询频率的查询词，收集自实地搜索和其AdWords自助广告系统中所使用的关键词。Google很可能对关键词搜索次数设置了上限值，凡搜索频率高于此阈值的查询词都将被纳入Hilltop系统，然后Hilltop系统再对收集的所有高查询频率关键词定期运行批处理，可能一个月一次。增量级的稍小规模的批处理可能会频繁一些。 同时，每个月将对Hilltop系统运行批处理后的结果对Google的万台服务器的数据库进行同步更新，但稍小规模的批处理的数据库更新会更加频繁一些。<br /><br />对于那些用户查询频率不算高，因而无此“荣幸”被纳入Hilltop算法的查询词语，Google仍将使用原来的算法并显示原来的排名结果。因而对于那些高度明确或专业化的关键词，由于它们被排除在新算法的范围之内，因而有望保持原来的排名。 <br /><br />Hilltop算法为何经过如此长时间才投入使用<br /><br />Google早在2003年2月就获得了该专利，但在实际投入使用前，需要首先保证新算法和Google当时所使用的页面等级和页面相关性系统的完全兼容性，所以需要对其兼容性做大量测试，然后再评估算法整合后所提供的结果，再做精工调整，然后是进一步的繁复测试…我想所有这些都需要大量时间。<br /><br />Google新算法的不利方面/瑕疵<br /><br />经过进一步分析，我们发现了该算法存在着的若干缺陷和不足： <br /><br />Hilltop的前提是每个专家文件都是完全公正的，且无欺骗和人工操纵成分。然而情况可能并非如此理想。专家文件的一个小小污点就可以对排名产生极大的负面影响。 <br /><br />Hilltop意图通过“权威性”专家文件的链接来确定一个网页的行业可信度，但又不能够明确保证这些所谓的“专家文件”的”“量”确是名副其实。 <br /><br />运行Hilltop算法需要大量的计算机处理能力，因而我们猜测Hilltop算法(可能)是每个月对收集到的全部高频率(热门)查询词运行一次批处理。由于Google算法将40%重心转移至Hilltop，且Hilltop算法运行后的得分会保持至下一次批处理，因而在此期间搜索结果很可能不会有太大变动。此外，由于“专家”网页的投票方式往往不会有太大变动，因而在某段时期内我们可能只会看到一些“陈旧”的搜索结果。这一点悖离了搜索引擎的“提供最新、最好”的查询结果的宗旨。除了“权威网页”，用户同样希望看到一些新鲜的内容，然而对“新”Google而言，用户只有寄望于那些查询频率不太高，从而未被纳入Hilltop系统的查询词语上看到“新鲜”的查询结果了。 <br /><br />新站点对热门查询词的排名的难度将越发加大。看来对于那些特别热门的查询词，Google对新网站或新内容的排名的门槛是越来越高了。 <br /><br />商业性站点要链向网络分类目录，贸易协会，政府贸易机构，教育机构，公益性组织的站点并非难事，故而这样的站点会占据搜索结果的前十名位置。 <br /><br /><br />哪些站点是Google新算法最可能的殃及者？<br /><br />成员站点/域群集/运行于相同服务器下的MLM(多层营销系统程序)程序。 <br /><br />过度依赖“页面”优化因子的网站。 <br /><br />依赖高度竞争性的查询词语来获得访问量的网站。<br /><br />对网站拥有者的若干建议：<br /><br />排名规则已发生重大改变，网站的成功推广需从提高PR值及获得更多来自“专家文件”的链接着手； <br /><br />尽可能为更多主流网上分类目录(DMOZ，Yahoo，About，LookSmart等)，贸易目录，黄页，贸易协会和资源页等所收录； <br /><br />避免使用域群集/成员程序或带有成员性质的系统； <br /><br />避免来自可疑的FFA站点及链接工厂的互惠链接。<br /><br />若干需要澄清的传言：<br /><br />关于“过度优化会受到惩罚”之说--过滤优化本身就是一种SPAM，因而受到惩罚也是理所当然的事情。然而当前大多数商业网站所受到的排名冲击并非由于受到惩罚，而是由Google将重心从页面因子转至非页面因子而造成的。网站的良好优化仍必不可少。 <br /><br />关于“建立外部链接不再重要”之说--建立链接流行度还是和从前一样举足轻重，甚至还有可能会更加重要。Google专利的页面等级算法仍旧占据举足轻重的地位。 <br /><br />关于“Google开始使用‘商业词’过滤名单”之说--Google并没有使用任何“过滤名单”来惩罚商业站点。Google也无意去“惩罚”或“筛掉”任何东西，它所力求的只是建立一个能够识别最具备相关性网页的系统。 <br /><br />站点收录进DMOZ，Google目录和商业目录收录会让Google认为该站点属商业性网站，从而对其进行惩罚--正相反，由于这些目录都是质量非常之高的“专家文件”，因而得到这些目录的链接不但不会受到惩罚，反而会带给你较高的收益。<br /><br />随着Google对其算法的大更新，我们不得不承认，要想让网站得到好的排名真是越来越不容易了。若只采用简单的优化技术，如元标识(Meta)或页面优化，几乎没办法得到理想排名。我们需要顾及很多的算法变量，而不仅仅是一个Meta Tags。</font>
				<a href="http://www.seoclub.cn/seo/index.htm" target="_blank">
						<font color="#0000ff" size="2">搜索引擎优化</font>
				</a>
				<font size="2">会更为专业化。老式的优化伎俩已经不管用或收效甚微了。现在需要计划和实施的是全方位的</font>
				<a href="http://www.seoclub.cn/seo/index.htm" target="_blank">
						<font color="#0000ff" size="2">SEO</font>
				</a>
				<font size="2">策略。为保证成效，</font>
				<a href="http://www.seoclub.cn/seo/index.htm" target="_blank">
						<font color="#0000ff" size="2">SEO</font>
				</a>
				<font size="2">专家现在需要做的是投入更多的智慧、研究、分析、计划和时间。这样的话，</font>
				<a href="http://www.seoclub.cn/seo/index.htm" target="_blank">
						<font color="#0000ff" size="2">SEO</font>
				</a>
				<font size="2">的优化“成本”亦将逐渐增高。<br /><br />PPC(付费点击)的价格会继续攀升。PPC广告方式不但会成为网上营销策略的一个主要组成部分，而且需要保证相应的搜索引擎访问量。现在，网站的外部链接和页面等级愈加重要。它对排名的影响更加重要。</font>
				<a href="http://www.seoclub.cn/seo/index.htm" target="_blank">
						<font color="#0000ff" size="2">搜索引擎优化</font>
				</a>
				<font size="2">和建立链接的结合已势在必行。此外，搜索引擎排名算法的更新不仅会越加频繁，而且幅度会越来越大。现在，定期的</font>
				<a href="http://www.seoclub.cn/seo/index.htm" target="_blank">
						<font color="#0000ff" size="2">搜索引擎优化</font>
				</a>
				<font size="2">维护变得尤为重要。对网站的</font>
				<a href="http://www.seoclub.cn/seo/index.htm" target="_blank">
						<font color="#0000ff" size="2">搜索引擎优化</font>
				</a>
				<font size="2">不仅是必须的，而且大有裨益。<br /><br />很多网站都丢掉了它们原来的好排名，因而尤其需要搜索优化专家。每一次更新算法都是对</font>
				<a href="http://www.seoclub.cn/seo/index.htm" target="_blank">
						<font color="#0000ff" size="2">搜索引擎优化</font>
				</a>
				<font size="2">人员名单的一次缩水。搜索引擎的优化和排名生意变得愈加困难，然而也愈加重要了。</font>
				<br />
		</p>
<img src ="http://www.cppblog.com/tx7do/aggbug/5783.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-04-17 18:45 <a href="http://www.cppblog.com/tx7do/archive/2006/04/17/5783.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>产生不重复随机数的简便算法</title><link>http://www.cppblog.com/tx7do/archive/2006/04/17/5775.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Mon, 17 Apr 2006 09:14:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/04/17/5775.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/5775.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/04/17/5775.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/5775.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/5775.html</trackback:ping><description><![CDATA[产生不重复随机数的算法能够解决诸如随机洗牌，抽彩等问题，在网上的一些算法自觉较繁，现给出简单的算法。以下源程序为1..36个数字，随机排列，产生不重复随机数。 
<div class="code"><span class="syntaxComment"><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">var<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />aa : array[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">36</span><span style="COLOR: #000000">] of </span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">[</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">]; </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">aa数组为需要随机排列的数组，</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_55_73_Open_Image" onclick="this.style.display='none'; Codehighlighter1_55_73_Open_Text.style.display='none'; Codehighlighter1_55_73_Closed_Image.style.display='inline'; Codehighlighter1_55_73_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_55_73_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_55_73_Closed_Text.style.display='none'; Codehighlighter1_55_73_Open_Image.style.display='inline'; Codehighlighter1_55_73_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_55_73_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_55_73_Open_Text"><span style="COLOR: #000000">{先把1..36按顺序给aa数组赋值}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />procedure TForm1.FormCreate(Sender: TObject);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />var<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />i:integer;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />begin<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> i:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> to </span><span style="COLOR: #000000">36</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"> begin<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />aa[i]:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">inttostr(i);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />bb[i]:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">inttostr(i);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />end;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />end;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img id="Codehighlighter1_217_224_Open_Image" onclick="this.style.display='none'; Codehighlighter1_217_224_Open_Text.style.display='none'; Codehighlighter1_217_224_Closed_Image.style.display='inline'; Codehighlighter1_217_224_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_217_224_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_217_224_Closed_Text.style.display='none'; Codehighlighter1_217_224_Open_Image.style.display='inline'; Codehighlighter1_217_224_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_217_224_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_217_224_Open_Text"><span style="COLOR: #000000">{随机进行排列}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />procedure TForm1.Button1Click(Sender: TObject);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />var<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />i,j:integer;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />swapa:</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">[</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">];<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />begin<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />randomize;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> i:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> to </span><span style="COLOR: #000000">36</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"> begin<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />j:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">random(</span><span style="COLOR: #000000">36</span><span style="COLOR: #000000">);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />swapa:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">aa[i];<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />aa[i]:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">aa[j];<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />aa[j]:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">swapa;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />end; </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">由此得到不重复的随机排列数字</span></div></span></div><img src ="http://www.cppblog.com/tx7do/aggbug/5775.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-04-17 17:14 <a href="http://www.cppblog.com/tx7do/archive/2006/04/17/5775.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>奇妙的二叉树：Huffman的贡献</title><link>http://www.cppblog.com/tx7do/archive/2006/04/17/5774.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Mon, 17 Apr 2006 09:13:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/04/17/5774.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/5774.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/04/17/5774.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/5774.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/5774.html</trackback:ping><description><![CDATA[奇妙的二叉树：Huffman的贡献 <br />关键字 Huffman <br /><br />提起 Huffman 这个名字，程序员们至少会联想到二叉树和二进制编码。的确，我们总以 Huffman 编码来概括 D.A.Huffman 个人对计算机领域特别是数据压缩领域的杰出贡献。我们知道，压缩 = 模型 + 编码，作为一种压缩方法，我们必须全面考虑其模型和编码两个模块的功效；但同时，模型和编码两个模块又相互具有独立性。举例来说，一个使用 Huffman 编码方法的程序，完全可以采用不同的模型来统计字符在信息中出现的概率。因此，我们这一章将首先围绕 Huffman 先生最为重要的贡献 —— Huffman 编码展开讨论，随后，我们再具体介绍可以和 Huffman 联合使用的概率模型。<br /><br />为什么是二叉树<br /><br />为什么压缩领域中的编码方法总和二叉树联系在一起呢？原因非常简单，回忆一下我们介绍过的“前缀编码”：为了使用不固定的码长表示单个字符，编码必须符合“前缀编码”的要求，即较短的编码决不能是较长编码的前缀。要构造符合这一要求的二进制编码体系，二叉树是最理想的选择。考察下面这棵二叉树：<br /><br />根(root)<br />0 | 1<br />+------+------+<br />0 | 1 0 | 1<br />+-----+-----+ +---+----+<br />| | | |<br />a | d e<br />0 | 1<br />+-----+-----+<br />| |<br />b c<br />要编码的字符总是出现在树叶上，假定从根向树叶行走的过程中，左转为0，右转为1，则一个字符的编码就是从根走到该字符所在树叶的路径。正因为字符只能出现在树叶上，任何一个字符的路径都不会是另一字符路径的前缀路径，符合要求的前缀编码也就构造成功了：<br /><br />a - 00 b - 010 c - 011 d - 10 e - 11<br />Shannon-Fano 编码<br /><br />进入 Huffman 先生构造的神奇二叉树之前，我们先来看一下它的前身，由 Claude Shannon 和 R.M.Fano 两人提出的 Shannon-Fano 编码。<br /><br />讨论之前，我们假定要编码字符的出现概率已经由某一模型统计出来，例如，对下面这串出现了五种字符的信息( 40 个字符长 ):<br /><br />cabcedeacacdeddaaabaababaaabbacdebaceada<br />五种字符的出现次数分别：a - 16，b - 7，c - 6，d - 6，e - 5。<br /><br />Shannon-Fano 编码的核心仍然是构造二叉树，构造的方式非常简单：<br /><br />1) 将给定符号按照其频率从大到小排序。对上面的例子，应该得到：<br /><br />a - 16<br />b - 7<br />c - 6<br />d - 6<br />e - 5<br />2) 将序列分成上下两部分，使得上部频率总和尽可能接近下部频率总和。我们有：<br /><br />a - 16<br />b - 7<br />-----------------<br />c - 6<br />d - 6<br />e - 5<br />3) 我们把第二步中划分出的上部作为二叉树的左子树，记 0，下部作为二叉树的右子树，记 1。<br /><br />4) 分别对左右子树重复 2 3 两步，直到所有的符号都成为二叉树的树叶为止。现在我们有如下的二叉树：<br /><br />根(root)<br />0 | 1<br />+------+------+<br />0 | 1 0 | 1<br />+-----+-----+ +---+----+<br />| | | |<br />a b c |<br />0 | 1<br />+-----+-----+<br />| |<br />d e<br />于是我们得到了此信息的编码表：<br /><br />a - 00 b - 01 c - 10 d - 110 e - 111<br />可以将例子中的信息编码为：<br /><br />cabcedeacacdeddaaabaababaaabbacdebaceada<br />10 00 01 10 111 110 111 00 10 00 10 ......<br />码长共 91 位。考虑用 ASCII 码表示上述信息需要 8 * 40 = 240 位，我们确实实现了数据压缩。<br /><br />Huffman 编码<br /><br />Huffman 编码构造二叉树的方法和 Shannon-Fano 正好相反，不是自上而下，而是从树叶到树根生成二叉树。现在，我们仍然使用上面的例子来学习 Huffman 编码方法。<br /><br />1) 将各个符号及其出现频率分别作为不同的小二叉树（目前每棵树只有根节点）。<br /><br />a(16) b(7) c(6) d(6) e(5)<br />2) 在 1 中得到的树林里找出频率值最小的两棵树，将他们分别作为左、右子树连成一棵大一些的二叉树，该二叉树的频率值为两棵子树频率值之和。对上面的例子，我们得到一个新的树林：<br /><br />| (11)<br />a(16) b(7) c(6) +---+---+ <br />| |<br />d e<br />3) 对上面得到的树林重复 2 的做法，直到所有符号都连入树中为止。这一步完成后，我们有这样的二叉树：<br /><br />根(root)<br />0 | 1<br />+------+----------------+<br />| 0 | 1<br />| +---------+-----------+<br />| 0 | 1 0 | 1<br />a +-------+------+ +-------+-------+<br />| | | |<br />b c d e <br />由此，我们可以建立和 Shannon-Fano 编码略微不同的编码表：<br /><br />a - 0 b - 100 c - 101 d - 110 e - 111<br />对例子中信息的编码为：<br /><br />cabcedeacacdeddaaabaababaaabbacdebaceada<br />101 0 100 101 111 110 111 0 101 0 101 ......<br />码长共 88 位。这比使用 Shannon-Fano 编码要更短一点。<br /><br />让我们回顾一下熵的知识，使用我们在第二章学到的计算方法，上面的例子中，每个字符的熵为：<br /><br />Ea = - log2(16 / 40) = 1.322<br />Eb = - log2( 7 / 40) = 2.515<br />Ec = - log2( 6 / 40) = 2.737<br />Ed = - log2( 6 / 40) = 2.737<br />Ee = - log2( 5 / 40) = 3.000<br />信息的熵为：<br /><br />E = Ea * 16 + Eb * 7 + Ec * 6 + Ed * 6 + Ee * 5 = 86.601<br />也就是说，表示该条信息最少需要 86.601 位。我们看到，Shannon-Fano 编码和 Huffman 编码都已经比较接近该信息的熵值了。同时，我们也看出，无论是 Shannon-Fano 还是 Huffman，都只能用近似的整数位来表示单个符号，而不是理想的小数位。我们可以将它们做一个对比：<br /><br />符号 理想位数 S-F 编码 Huffman 编码<br />( 熵 ) 需要位数 需要位数<br />----------------------------------------------------<br />a 1.322 2 1<br />b 2.515 2 3<br />c 2.737 2 3<br />d 2.737 3 3<br />e 3.000 3 3<br />----------------------------------------------------<br />总 计 86。601 91 88<br />这就是象 Huffman 这样的整数位编码方式无法达到最理想的压缩效果的原因。<br /><br />为 Huffman 编码选择模型（附范式 Huffman 编码）<br /><br />最简单，最容易被 Huffman 编码利用的模型是“静态统计模型”，也就是说在编码前统计要编码的信息中所有字符的出现频率，让后根据统计出的信息建立编码树，进行编码。这种模型的缺点是显而易见的：首先，对数据量较大的信息，静态统计要消耗大量的时间；其次，必须保存统计出的结果以便解码时构造相同的编码树，或者直接保存编码树本身，而且，对于每次静态统计，都有不同的结果，必须分别予以保存，这要消耗大量的空间（这意味着压缩效率的下降）；再次，事实上，即使不将编码树计算在内，对通常含有 0 - 255 字符集的计算机文件来说，静态统计模型统计出的频率是字符在整个文件中的出现频率，往往反映不出字符在文件中不同局部出现频率的变化情况，使用这一频率进行压缩，大多数情况下得不到太好压缩效果，文件有时甚至在压缩后反而增大了。所以，“静态统计模型”一般仅作为复杂算法的某一部分出现，在信息的某一局部完成压缩功能。我们很难将其用于独立的压缩系统。<br /><br />有一种有效的“静态统计模型”的替代方案，如果我们要压缩的所有信息具有某些共同的特性，也即在分布上存在着共同的特征，比如我们要压缩的是普通的英文文本，那么，字母 a 或者字母 e 的出现频率应当是大致稳定的。使用语言学家事先已经建立好的字母频率表来进行压缩和解压缩，不但不用保存多份统计信息，而且一般说来对该类文件有着较好的压缩效果。这种方案除了适应性不太强以外，偶尔还会有一些尴尬的时候。读一遍下面这段话：<br /><br />If Youth，throughout all history， had had a champion to stand up for it； to show a doubting world that a child can think；and， possibly， do it practically； you wouldn't constantly run across folks today who claim that "a child don't know anything." - Gadsby by E.V.Wright, 1939.<br /><br />发现什么问题了吗？哦，整段话中竟没有出现一次英文中出现频率最高的字母 e ！真让人惊讶，但没有办法，事先拟定的频率分布总有意外的时候。<br /><br />对英文或中文文本，有一种比较实用的静态模型：不是把字符而是把英文单词或中文词语作为统计频率和编码的单位进行压缩。也就是说，每次编码的不再是 a b c 这样的单个符号，而是 the look flower 这样的单词。这种压缩方式可以达到相当不错的压缩效果，并被广泛地用于全文检索系统。<br /><br />对基于词的编码方式，需要解决几个技术难点。首先是分词的问题，英文单词可以由词间空格分隔，但中文怎么办呢？其实，有很多中文分词算法可以解决这个问题，本书就不再详细介绍了。王笨笨就曾开发过一个不错的分词模块，但希望通过收取一定报酬的方式提供该模块，如有需要，请和王笨笨 E-Mail 联系。一旦我们将词语分离出来，我们就可以对每个词进行频率统计，然后建立 Huffman 编码树，输出编码时，一个编码将代替一个词语。但要注意，英文和汉语的单词数量都在几万到十几万左右，也就是说，我们的 Huffman 编码树将拥有十几万个叶子节点，这对于一棵树来说太大太大了，系统将无力承担所需要的资源，这怎么办呢？我们可以暂时抛开树结构，采用另一种构造 Huffman 编码的方式——范式 Huffman 编码。<br /><br />范式 Huffman 编码(Canonical Huffman Code)的基本思路是：并非只有使用二叉树建立的前缀编码才是 Huffman 编码，只要符合(1)是前缀编码(2)某一字符编码长度和使用二叉树建立的该字符的编码长度相同这两个条件的编码都可以叫做 Huffman 编码。考虑对下面六个单词的编码：<br /><br />符号 出现次数 传统 Huffman 编码 范式 Huffman 编码<br />------------------------------------------------------------<br />单词1 10 000 000<br />单词2 11 001 001<br />单词3 12 100 010<br />单词4 13 101 011<br />单词5 22 01 10<br />单词6 23 11 11<br />注意到范式 Huffman 编码的独特之处了吗？你无法使用二叉树来建立这组编码，但这组编码确实能起到和 Huffman 编码相同的作用。而且，范式 Huffman 编码具有一个明显的特点：当我们把要编码的符号按照其频率从小到大排列时，如果把范式 Huffman 编码本身作为单词的话，也呈现出从小到大的字典顺序。<br /><br />构造范式 Huffman 编码的方法大致是：<br /><br />1) 统计每个要编码符号的频率。<br /><br />2) 根据这些频率信息求出该符号在传统 Huffman 编码树中的深度（也就是表示该符号所需要的位数 - 编码长度）。因为我们关心的仅仅是该符号在树中的深度，我们完全没有必要构造二叉树，仅用一个数组就可以模拟二叉树的创建过程并得到符号的深度，具体方法这里就不详述了。<br /><br />3) 分别统计从最大编码长度 maxlength 到 1 的每个长度对应了多少个符号。根据这一信息从 maxlength 个 0 开始以递增顺序为每个符号分配编码。例如，编码长度为 5 的符号有 4 个，长度为 3 的有 1 个，长度为 2 的有 3 个，则分配的编码依次为： 00000 00001 00010 00011 001 01 10 11<br /><br />4) 编码输出压缩信息，并保存按照频率顺序排列的符号表，然后保存每组同样长度编码中的最前一个编码以及该组中的编码个数。<br /><br />现在完全可以不依赖任何树结构进行高速解压缩了。而且在整个压缩、解压缩过程中需要的空间比传统 Huffman 编码少得多。<br /><br />最后要提到的是，Huffman 编码可以采用自适应模型，根据已经编码的符号频率决定下一个符号的编码。这时，我们无需为解压缩预先保存任何信息，整个编码是在压缩和解压缩过程中动态创建的，而且自适应编码由于其符号频率是根据信息内容的变化动态得到的，更符合符号的局部分布规律，因此在压缩效果上比静态模型好许多。但是，采用自适应模型必须考虑编码表的动态特性，即编码表必须可以随时更新以适应符号频率的变化。对于 Huffman 编码来说，我们很难建立能够随时更新的二叉树，使用范式 Huffman 编码是个不错的选择，但依然存在不少技术上的难题。幸好，如果愿意的话，我们可以暂时不考虑自适应模型的 Huffman 编码，因为对于自适应模型我们还有许多更好的选择，下面几章将要谈到的算术编码、字典编码等更为适合采用自适应模型，我们将在其中深入探讨自适应模型的各种实现方法。<img src ="http://www.cppblog.com/tx7do/aggbug/5774.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-04-17 17:13 <a href="http://www.cppblog.com/tx7do/archive/2006/04/17/5774.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>椭圆曲线——密码体制(ECC)</title><link>http://www.cppblog.com/tx7do/archive/2006/04/17/5772.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Mon, 17 Apr 2006 09:12:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/04/17/5772.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/5772.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/04/17/5772.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/5772.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/5772.html</trackback:ping><description><![CDATA[2002年，美国SUN公司将其开发的椭圆加密技术赠送给开放源代码工程<br /><br />公钥密码体制根据其所依据的难题一般分为三类：<b>大整数分解问题类、离散对数问题类、椭圆曲线类</b>。有时也把椭圆曲线类归为离散对数类。 <br /><br />椭圆曲线密码体制来源于对椭圆曲线的研究，所谓椭圆曲线指的是由韦尔斯特拉斯（Weierstrass）方程： 
<div class="code">y2+a1xy+a3y=x3+a2x2+a4x+a6 (1) </div>所确定的平面曲线。其中系数ai(I=1,2,…,6)定义在某个域上，可以是有理数域、实数域、复数域，还可以是有限域GF（pr），椭圆曲线密码体制中用到的椭圆曲线都是定义在有限域上的。 <br /><br />椭圆曲线上所有的点外加一个叫做无穷远点的特殊点构成的集合连同一个定义的加法运算构成一个Abel群。在等式 
<div class="code">mP=P+P+…+P=Q (2)</div><br /><br />中，已知m和点P求点Q比较容易，反之已知点Q和点P求m却是相当困难的，这个问题称为椭圆曲线上点群的离散对数问题。椭圆曲线密码体制正是利用这个困难问题设计而来。椭圆曲线应用到密码学上最早是由Neal Koblitz 和Victor Miller在1985年分别独立提出的。 <br /><br />椭圆曲线密码体制是目前已知的公钥体制中，对每比特所提供加密强度最高的一种体制。解椭圆曲线上的离散对数问题的最好算法是Pollard rho方法，其时间复杂度为，是完全指数阶的。其中n为等式(2)中m的二进制表示的位数。当n=234, 约为2117，需要1.6x1023 MIPS 年的时间。而我们熟知的RSA所利用的是大整数分解的困难问题，目前对于一般情况下的因数分解的最好算法的时间复杂度是子指数阶的，当n=2048时，需要2x1020MIPS年的时间。也就是说当RSA的密钥使用2048位时，ECC的密钥使用234位所获得的安全强度还高出许多。它们之间的密钥长度却相差达9倍，当ECC的密钥更大时它们之间差距将更大。更ECC密钥短的优点是非常明显的，随加密强度的提高，密钥长度变化不大。 <br /><br />德国、日本、法国、美国、加拿大等国的很多密码学研究小组及一些公司实现了椭圆曲线密码体制，我国也有一些密码学者做了这方面的工作。许多标准化组织已经或正在制定关于椭圆曲线的标准，同时也有许多的厂商已经或正在开发基于椭圆曲线的产品。对于椭圆曲线密码的研究也是方兴未艾，从ASIACRYPTO’98上专门开辟了ECC的栏目可见一斑。 <br /><br />在椭圆曲线密码体制的标准化方面，IEEE、ANSI、ISO、IETF、ATM等都作了大量的工作，它们所开发的椭圆曲线标准的文档有：IEEE P1363 P1363a、ANSI X9.62 X9.63、 ISO/IEC14888等。<br /><br />2003年5月12日中国颁布的无线局域网国家标准 GB15629.11 中，包含了全新的WAPI(WLAN Authentication and Privacy Infrastructure)安全机制，能为用户的WLAN系统提供全面的安全保护。这种安全机制由 WAI和WPI两部分组成，分别实现对用户身份的鉴别和对传输的数据加密。WAI采用公开密钥密码体制，利用证书来对WLAN系统中的用户和AP进行认证。证书里面包含有证书颁发者(ASU)的公钥和签名以及证书持有者的公钥和签名，这里的签名采用的就是椭圆曲线ECC算法。<br /><br />加拿大Certicom公司是国际上最著名的ECC密码技术公司,已授权300多家企业使用ECC密码技术，包括Cisco 系统有限公司、摩托罗拉、Palm等企业。Microsoft将Certicom公司的VPN嵌入微软视窗移动2003系统中。<br />以下资料摘自：<a title="http://www.hids.com.cn/data.asp" href="http://www.hids.com.cn/data.asp" target="_blank">http://www.hids.com.cn/data.asp</a><br /><br />公钥密码系统的加密算法ECC与RSA的对比 <br />第六届国际密码学会议对应用于公钥密码系统的加密算法推荐了两种：基于大整数因子分解问题（IFP）的RSA算法和基于椭圆曲线上离散对数计算问题（ECDLP）的ECC算法。RSA算法的特点之一是数学原理简单、在工程应用中比较易于实现，但它的单位安全强度相对较低。目前用国际上公认的对于RSA算法最有效的攻击方法--一般数域筛(NFS)方法去破译和攻击RSA算法，它的破译或求解难度是亚指数级的。ECC算法的数学理论非常深奥和复杂，在工程应用中比较难于实现，但它的单位安全强度相对较高。用国际上公认的对于ECC算法最有效的攻击方法--Pollard rho方法去破译和攻击ECC算法，它的破译或求解难度基本上是指数级的。正是由于RSA算法和ECC算法这一明显不同，使得ECC算法的单位安全强度高于RSA算法，也就是说，要达到同样的安全强度，ECC算法所需的密钥长度远比RSA算法低（见表1和图1）。这就有效地解决了为了提高安全强度必须增加密钥长度所带来的工程实现难度的问题。（见表2）<br /><br /><div style="OVERFLOW-X: auto; WIDTH: 100%"><a href="http://wlan.sjtu.edu.cn/img/wapi/54_table1.gif" target="_blank"><img height="223" alt="http://wlan.sjtu.edu.cn/img/wapi/54_table1.gif" src="http://wlan.sjtu.edu.cn/img/wapi/54_table1.gif" width="534" onload="javascript:DrawImage(this);" /></a></div><br /><div style="OVERFLOW-X: auto; WIDTH: 100%"><a href="http://wlan.sjtu.edu.cn/img/wapi/54_fig1.gif" target="_blank"><img height="409" alt="http://wlan.sjtu.edu.cn/img/wapi/54_fig1.gif" src="http://wlan.sjtu.edu.cn/img/wapi/54_fig1.gif" width="524" onload="javascript:DrawImage(this);" /></a></div><br /><div style="OVERFLOW-X: auto; WIDTH: 100%"><a href="http://wlan.sjtu.edu.cn/img/wapi/54_table2.gif" target="_blank"><img height="251" alt="http://wlan.sjtu.edu.cn/img/wapi/54_table2.gif" src="http://wlan.sjtu.edu.cn/img/wapi/54_table2.gif" width="534" onload="javascript:DrawImage(this);" /></a></div><img src ="http://www.cppblog.com/tx7do/aggbug/5772.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-04-17 17:12 <a href="http://www.cppblog.com/tx7do/archive/2006/04/17/5772.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>归并排序算法</title><link>http://www.cppblog.com/tx7do/archive/2006/04/17/5771.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Mon, 17 Apr 2006 09:10:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/04/17/5771.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/5771.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/04/17/5771.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/5771.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/5771.html</trackback:ping><description><![CDATA[合并排序（MERGE SORT）是又一类不同的排序方法，合并的含义就是将两个或两个以上的有序数据序列合并成一个新的有序数据序列，因此它又叫归并算法。它的基本思想就是假设数组A有N个元素，那么可以看成数组A是又N个有序的子序列组成，每个子序列的长度为1，然后再两两合并，得到了一个 N/2 个长度为2或1的有序子序列，再两两合并，如此重复，值得得到一个长度为N的有序数据序列为止，这种排序方法称为2—路合并排序。 <br /><br />例如数组A有7个数据，分别是： 49 38 65 97 76 13 27，那么采用归并排序算法的操作过程如图7所示： <br /><br />初始值 [49] [38] [65] [97] [76] [13] [27] <br /><br />看成由长度为1的7个子序列组成 <br /><br />第一次合并之后 [38 49] [65 97] [13 76] [27] <br /><br />看成由长度为1或2的4个子序列组成 <br /><br />第二次合并之后 [38 49 65 97] [13 27 76] <br /><br />看成由长度为4或3的2个子序列组成 <br /><br />第三次合并之后 [13 27 38 49 65 76 97] <br /><br />图6 归并排序算法过程图 <br /><br />合并算法的核心操作就是将一维数组中前后相邻的两个两个有序序列合并成一个有序序列。合并算法也可以采用递归算法来实现，形式上较为简单,但实用性很差。 <br /><br />合并算法的合并次数是一个非常重要的量,根据计算当数组中有3到4个元素时,合并次数是2次,当有5到8个元素时,合并次数是3次,当有9到16个元素时,合并次数是4次，按照这一X规律,当有N个子序列时可以推断出合并的次数是X(2 &gt;=N,符合此条件的最小那个X)。 <br />源程序：
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">program hebing; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />  n</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />var <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />  a:array[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">..n] of integer; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />  i:integer; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> procedure init; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> var <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />    i:integer; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> begin <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> i:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> to n </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"> read(a[i]); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> readln; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> end; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> procedure merge(low,mid,high:integer); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> var <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> h,i,j,k:integer; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> b:array[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">..n] of integer; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> begin <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> h:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">low; i:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">low; j:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">mid</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> (h</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">mid) and (j</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">high) </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"> begin <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (a[h]</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">a[j]) then begin<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />   b[i]:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">a[h]; h:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">h</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> end </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> begin <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> b[i]:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">a[j]; j:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> end; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> i:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> end; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">mid then <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> k:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">j to high </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"> begin <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />   b[i]:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">a[k]; i:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> end </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> k:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">h to mid </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"> begin <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> b[i]:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">a[k]; i:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> end; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> k:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">low to high </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"> a[k]:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">b[k];<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> end; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> procedure mergesort(low,high:integer); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> var <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> mid:integer; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> begin <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> low</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">high then begin <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> mid:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">(low</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">high) div </span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> mergesort(low,mid); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> mergesort(mid</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,high); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> merge(low,mid,high); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> end; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> end;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span></div><img src ="http://www.cppblog.com/tx7do/aggbug/5771.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-04-17 17:10 <a href="http://www.cppblog.com/tx7do/archive/2006/04/17/5771.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>动态规划-航线设置</title><link>http://www.cppblog.com/tx7do/archive/2006/04/17/5769.html</link><dc:creator>杨粼波</dc:creator><author>杨粼波</author><pubDate>Mon, 17 Apr 2006 09:01:00 GMT</pubDate><guid>http://www.cppblog.com/tx7do/archive/2006/04/17/5769.html</guid><wfw:comment>http://www.cppblog.com/tx7do/comments/5769.html</wfw:comment><comments>http://www.cppblog.com/tx7do/archive/2006/04/17/5769.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tx7do/comments/commentRss/5769.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tx7do/services/trackbacks/5769.html</trackback:ping><description><![CDATA[问题描述:美丽的莱茵河畔,每边都分布着N个城市,两边的城市都是唯一对应的友好城市,现需要在友好城市开通航线以加强往来.但因为莱茵河常年大雾,如果开设的航线发生交叉现象就有可能出现碰船的现象.现在要求近可能多地开通航线并且使航线不能相交!<br /><br />假如你是一个才华横溢的设计师,该如何设置友好城市间的航线使的航线数又最大又不相交呢?<br /><br />分析:此问题可以演化成求最大不下降序列来完成.源程序如下: 
<div class="code"><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_17_33_Open_Image" onclick="this.style.display='none'; Codehighlighter1_17_33_Open_Text.style.display='none'; Codehighlighter1_17_33_Closed_Image.style.display='inline'; Codehighlighter1_17_33_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_17_33_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_17_33_Closed_Text.style.display='none'; Codehighlighter1_17_33_Open_Image.style.display='inline'; Codehighlighter1_17_33_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #000000">program dongtai; </span><span id="Codehighlighter1_17_33_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_17_33_Open_Text"><span style="COLOR: #000000">{动态规划之友好城市航线设置问题}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />var<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> d:array[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">1000</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">] of integer;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> i,j,k,n,L,p:integer;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img id="Codehighlighter1_126_131_Open_Image" onclick="this.style.display='none'; Codehighlighter1_126_131_Open_Text.style.display='none'; Codehighlighter1_126_131_Closed_Image.style.display='inline'; Codehighlighter1_126_131_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_126_131_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_126_131_Closed_Text.style.display='none'; Codehighlighter1_126_131_Open_Image.style.display='inline'; Codehighlighter1_126_131_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> procedure print(L:integer); </span><span id="Codehighlighter1_126_131_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_126_131_Open_Text"><span style="COLOR: #000000">{打印结果}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> begin<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> writeLn(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">最多可设置的航线数是 : </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,k);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> repeat<br /><img id="Codehighlighter1_206_222_Open_Image" onclick="this.style.display='none'; Codehighlighter1_206_222_Open_Text.style.display='none'; Codehighlighter1_206_222_Closed_Image.style.display='inline'; Codehighlighter1_206_222_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_206_222_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_206_222_Closed_Text.style.display='none'; Codehighlighter1_206_222_Open_Image.style.display='inline'; Codehighlighter1_206_222_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> writeLn(d[L,</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]:</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,d[L,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">]:</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">); </span><span id="Codehighlighter1_206_222_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_206_222_Open_Text"><span style="COLOR: #000000">{输出可以设置航线的友好城市代码}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> L:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">d[L,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">]<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> untiL L</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> end;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />begin<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> writeLn(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">输入友好城市对数: </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> readLn(n);<br /><img id="Codehighlighter1_327_330_Open_Image" onclick="this.style.display='none'; Codehighlighter1_327_330_Open_Text.style.display='none'; Codehighlighter1_327_330_Closed_Image.style.display='inline'; Codehighlighter1_327_330_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_327_330_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_327_330_Closed_Text.style.display='none'; Codehighlighter1_327_330_Open_Image.style.display='inline'; Codehighlighter1_327_330_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> writeLn(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">输入友好城市对（友好城市放在同一行:</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">); </span><span id="Codehighlighter1_327_330_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_327_330_Open_Text"><span style="COLOR: #000000">{输入}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> i:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> to n </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_374_396_Open_Image" onclick="this.style.display='none'; Codehighlighter1_374_396_Open_Text.style.display='none'; Codehighlighter1_374_396_Closed_Image.style.display='inline'; Codehighlighter1_374_396_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_374_396_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_374_396_Closed_Text.style.display='none'; Codehighlighter1_374_396_Open_Image.style.display='inline'; Codehighlighter1_374_396_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> readLn(d[i,</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">],d[i,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">]); </span><span id="Codehighlighter1_374_396_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_374_396_Open_Text"><span style="COLOR: #000000">{D[I，</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]表示起点，D[I，</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">]表示终点}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> i:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> to n </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> begin<br /><img id="Codehighlighter1_435_453_Open_Image" onclick="this.style.display='none'; Codehighlighter1_435_453_Open_Text.style.display='none'; Codehighlighter1_435_453_Closed_Image.style.display='inline'; Codehighlighter1_435_453_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_435_453_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_435_453_Closed_Text.style.display='none'; Codehighlighter1_435_453_Open_Image.style.display='inline'; Codehighlighter1_435_453_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> d[i,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">]:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">; </span><span id="Codehighlighter1_435_453_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_435_453_Open_Text"><span style="COLOR: #000000">{D[I，</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">]表示可以设置的航线条数}</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_466_505_Open_Image" onclick="this.style.display='none'; Codehighlighter1_466_505_Open_Text.style.display='none'; Codehighlighter1_466_505_Closed_Image.style.display='inline'; Codehighlighter1_466_505_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_466_505_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_466_505_Closed_Text.style.display='none'; Codehighlighter1_466_505_Open_Image.style.display='inline'; Codehighlighter1_466_505_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> d[i,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">]:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_466_505_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_466_505_Open_Text"><span style="COLOR: #000000">{D[I，</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">]表示后继，即下一条航线从哪里开始设置，为0表示不能设置下一条航线}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> end;<br /><img id="Codehighlighter1_536_549_Open_Image" onclick="this.style.display='none'; Codehighlighter1_536_549_Open_Text.style.display='none'; Codehighlighter1_536_549_Closed_Image.style.display='inline'; Codehighlighter1_536_549_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_536_549_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_536_549_Closed_Text.style.display='none'; Codehighlighter1_536_549_Open_Image.style.display='inline'; Codehighlighter1_536_549_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> i:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">n</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> downto </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_536_549_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_536_549_Open_Text"><span style="COLOR: #000000">{从倒数第二个城市开始规划}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> begin<br /><img id="Codehighlighter1_571_603_Open_Image" onclick="this.style.display='none'; Codehighlighter1_571_603_Open_Text.style.display='none'; Codehighlighter1_571_603_Closed_Image.style.display='inline'; Codehighlighter1_571_603_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_571_603_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_571_603_Closed_Text.style.display='none'; Codehighlighter1_571_603_Open_Image.style.display='inline'; Codehighlighter1_571_603_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> L:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; p:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; </span><span id="Codehighlighter1_571_603_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_571_603_Open_Text"><span style="COLOR: #000000">{L表示本城市后面可以设置的航线数，P表示下条航线从哪个城市开始}</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_625_659_Open_Image" onclick="this.style.display='none'; Codehighlighter1_625_659_Open_Text.style.display='none'; Codehighlighter1_625_659_Closed_Image.style.display='inline'; Codehighlighter1_625_659_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_625_659_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_625_659_Closed_Text.style.display='none'; Codehighlighter1_625_659_Open_Image.style.display='inline'; Codehighlighter1_625_659_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> j:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> to n </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_625_659_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_625_659_Open_Text"><span style="COLOR: #000000">{找出本城市后面可以设置的最大航线数和小条航线到底从哪个城市开始设置}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (d[i,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">] L) then <br /><img id="Codehighlighter1_683_708_Open_Image" onclick="this.style.display='none'; Codehighlighter1_683_708_Open_Text.style.display='none'; Codehighlighter1_683_708_Closed_Image.style.display='inline'; Codehighlighter1_683_708_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_683_708_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_683_708_Closed_Text.style.display='none'; Codehighlighter1_683_708_Open_Image.style.display='inline'; Codehighlighter1_683_708_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> </span><span id="Codehighlighter1_683_708_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_683_708_Open_Text"><span style="COLOR: #000000">{如果本城市I的终点小于后面城市的终点（即不相交）}</span></span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_710_729_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_710_729_Open_Text"><span style="COLOR: #000000">{并且此城市后面可以设置的航线数大于L}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> begin<br /><img id="Codehighlighter1_750_767_Open_Image" onclick="this.style.display='none'; Codehighlighter1_750_767_Open_Text.style.display='none'; Codehighlighter1_750_767_Closed_Image.style.display='inline'; Codehighlighter1_750_767_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_750_767_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_750_767_Closed_Text.style.display='none'; Codehighlighter1_750_767_Open_Image.style.display='inline'; Codehighlighter1_750_767_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> L:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">d[j,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">]; </span><span id="Codehighlighter1_750_767_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_750_767_Open_Text"><span style="COLOR: #000000">{那么L等于城市J的可以设置航线数}</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_775_792_Open_Image" onclick="this.style.display='none'; Codehighlighter1_775_792_Open_Text.style.display='none'; Codehighlighter1_775_792_Closed_Image.style.display='inline'; Codehighlighter1_775_792_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_775_792_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_775_792_Closed_Text.style.display='none'; Codehighlighter1_775_792_Open_Image.style.display='inline'; Codehighlighter1_775_792_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> p:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">j </span><span id="Codehighlighter1_775_792_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_775_792_Open_Text"><span style="COLOR: #000000">{P等于可以设置下条航线的城市代码}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> end;<br /><img id="Codehighlighter1_813_834_Open_Image" onclick="this.style.display='none'; Codehighlighter1_813_834_Open_Text.style.display='none'; Codehighlighter1_813_834_Closed_Image.style.display='inline'; Codehighlighter1_813_834_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_813_834_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_813_834_Closed_Text.style.display='none'; Codehighlighter1_813_834_Open_Image.style.display='inline'; Codehighlighter1_813_834_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> L</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"> then </span><span id="Codehighlighter1_813_834_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_813_834_Open_Text"><span style="COLOR: #000000">{如果本城市后面总共可以设置的航线数</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">0则}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> begin<br /><img id="Codehighlighter1_857_887_Open_Image" onclick="this.style.display='none'; Codehighlighter1_857_887_Open_Text.style.display='none'; Codehighlighter1_857_887_Closed_Image.style.display='inline'; Codehighlighter1_857_887_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_857_887_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_857_887_Closed_Text.style.display='none'; Codehighlighter1_857_887_Open_Image.style.display='inline'; Codehighlighter1_857_887_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> d[i,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">]:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">L</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">; </span><span id="Codehighlighter1_857_887_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_857_887_Open_Text"><span style="COLOR: #000000">{本城市可以设置的航线数在下个城市可以设置航线数的基础上加1}</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_900_919_Open_Image" onclick="this.style.display='none'; Codehighlighter1_900_919_Open_Text.style.display='none'; Codehighlighter1_900_919_Closed_Image.style.display='inline'; Codehighlighter1_900_919_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_900_919_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_900_919_Closed_Text.style.display='none'; Codehighlighter1_900_919_Open_Image.style.display='inline'; Codehighlighter1_900_919_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> d[i,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">]:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">p </span><span id="Codehighlighter1_900_919_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_900_919_Open_Text"><span style="COLOR: #000000">{D[I，</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">]等于本城市后续城市的代码}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> end<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> end;<br /><img id="Codehighlighter1_944_975_Open_Image" onclick="this.style.display='none'; Codehighlighter1_944_975_Open_Text.style.display='none'; Codehighlighter1_944_975_Closed_Image.style.display='inline'; Codehighlighter1_944_975_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_944_975_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_944_975_Closed_Text.style.display='none'; Codehighlighter1_944_975_Open_Image.style.display='inline'; Codehighlighter1_944_975_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> k:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">d[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">]; </span><span id="Codehighlighter1_944_975_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_944_975_Open_Text"><span style="COLOR: #000000">{K为可以设置最大航线数，假设初值为第一个城市可以设置的航线数}</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_984_1000_Open_Image" onclick="this.style.display='none'; Codehighlighter1_984_1000_Open_Text.style.display='none'; Codehighlighter1_984_1000_Closed_Image.style.display='inline'; Codehighlighter1_984_1000_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_984_1000_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_984_1000_Closed_Text.style.display='none'; Codehighlighter1_984_1000_Open_Image.style.display='inline'; Codehighlighter1_984_1000_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> L:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">; </span><span id="Codehighlighter1_984_1000_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_984_1000_Open_Text"><span style="COLOR: #000000">{L为城市代码，初值为第一个城市}</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_1020_1060_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1020_1060_Open_Text.style.display='none'; Codehighlighter1_1020_1060_Closed_Image.style.display='inline'; Codehighlighter1_1020_1060_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_1020_1060_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1020_1060_Closed_Text.style.display='none'; Codehighlighter1_1020_1060_Open_Image.style.display='inline'; Codehighlighter1_1020_1060_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> i:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000"> to n </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_1020_1060_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_1020_1060_Open_Text"><span style="COLOR: #000000">{找出可以设置航线的最大值，赋值给K，同时L记下哪个可以设置最大航线数的城市代码}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> d[i,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">k then<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> begin<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> k:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">d[i,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">];<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> L:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">i<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> end;<br /><img id="Codehighlighter1_1129_1173_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1129_1173_Open_Text.style.display='none'; Codehighlighter1_1129_1173_Closed_Image.style.display='inline'; Codehighlighter1_1129_1173_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_1129_1173_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1129_1173_Closed_Text.style.display='none'; Codehighlighter1_1129_1173_Open_Image.style.display='inline'; Codehighlighter1_1129_1173_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> i:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> to n </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_1129_1173_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_1129_1173_Open_Text"><span style="COLOR: #000000">{打印结果，因为有可能有多种方案，所以只要哪个城市可以设置的航线数等于最大值K就打印结果}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> d[i,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">k then print(i)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />end.</span></div></div><img src ="http://www.cppblog.com/tx7do/aggbug/5769.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tx7do/" target="_blank">杨粼波</a> 2006-04-17 17:01 <a href="http://www.cppblog.com/tx7do/archive/2006/04/17/5769.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>