﻿<?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++博客-陋居-随笔分类-Arithmetic</title><link>http://www.cppblog.com/softko/category/14124.html</link><description>淡薄名利,修身养性</description><language>zh-cn</language><lastBuildDate>Wed, 22 Jun 2011 09:08:07 GMT</lastBuildDate><pubDate>Wed, 22 Jun 2011 09:08:07 GMT</pubDate><ttl>60</ttl><item><title>各种排序算法介绍</title><link>http://www.cppblog.com/softko/archive/2011/06/17/148828.html</link><dc:creator>eircQ</dc:creator><author>eircQ</author><pubDate>Fri, 17 Jun 2011 00:09:00 GMT</pubDate><guid>http://www.cppblog.com/softko/archive/2011/06/17/148828.html</guid><wfw:comment>http://www.cppblog.com/softko/comments/148828.html</wfw:comment><comments>http://www.cppblog.com/softko/archive/2011/06/17/148828.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/softko/comments/commentRss/148828.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/softko/services/trackbacks/148828.html</trackback:ping><description><![CDATA[<div>排序算法是一种基本并且常用的算法。由于实际工作中处理的数量巨大，所以排序算法对算法本身的速度要求很高。<br /><br />&nbsp; 而一般我们所谓的算法的性能主要是指算法的复杂度，一般用O方法来表示。在后面我将给出详细的说明。<br /><br />&nbsp; 对于排序的算法我想先做一点简单的介绍，也是给这篇文章理一个提纲。<br /><br />&nbsp; 我将按照算法的复杂度，从简单到难来分析算法。<br /><br />&nbsp; 第一部分是简单排序算法，后面你将看到他们的共同点是算法复杂度为O(N*N)（因为没有使用word,所以无法打出上标和下标）。<br /><br />&nbsp; 第二部分是高级排序算法，复杂度为O(Log2(N))。这里我们只介绍一种算法。另外还有几种算法因为涉及树与堆的概念，所以这里不于讨论。<br /><br />&nbsp; 第三部分类似动脑筋。这里的两种算法并不是最好的（甚至有最慢的），但是算法本身比较奇特，值得参考（编程的角度）。同时也可以让我们从另外的角度来认识这个问题。<br /><br />&nbsp; 第四部分是我送给大家的一个餐后的甜点&#8212;&#8212;一个基于模板的通用快速排序。由于是模板函数可以对任何数据类型排序（抱歉，里面使用了一些论坛专家的呢称）。 <br /><br /><br />&nbsp; 现在，让我们开始吧： <br />&nbsp;&nbsp; <br />一、简单排序算法 <br />由于程序比较简单，所以没有加什么注释。所有的程序都给出了完整的运行代码，并在我的VC环境下运行通过。因为没有涉及MFC和WINDOWS的内容，所以在BORLAND C++的平台上应该也不会有什么问题的。在代码的后面给出了运行过程示意，希望对理解有帮助。 <br /> <br />1.冒泡法： <br />这是最原始，也是众所周知的最慢的算法了。他的名字的由来因为它的工作看来象是冒泡： <br />#include &lt;iostream.h&gt; <br /> <br />void BubbleSort(int* pData,int Count) <br />{ <br />&nbsp;&nbsp;int iTemp; <br />&nbsp;&nbsp;for(int i=1;i&lt;Count;i++) <br />&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;for(int j=Count-1;j&gt;=i;j--) <br />&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(pData[j]&lt;pData[j-1]) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iTemp = pData[j-1]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData[j-1] = pData[j]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData[j] = iTemp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;} <br />} <br /> <br />void main() <br />{ <br />&nbsp;&nbsp;int data[] = {10,9,8,7,6,5,4}; <br />&nbsp;&nbsp;BubbleSort(data,7); <br />&nbsp;&nbsp;for (int i=0;i&lt;7;i++) <br />&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;data[i]&lt;&lt;" "; <br />&nbsp;&nbsp;cout&lt;&lt;"\n"; <br />} <br /> <br />倒序(最糟情况) <br />第一轮：10,9,8,7-&gt;10,9,7,8-&gt;10,7,9,8-&gt;7,10,9,8(交换3次) <br />第二轮：7,10,9,8-&gt;7,10,8,9-&gt;7,8,10,9(交换2次) <br />第一轮：7,8,10,9-&gt;7,8,9,10(交换1次) <br />循环次数：6次 <br />交换次数：6次 <br /> <br />其他： <br />第一轮：8,10,7,9-&gt;8,10,7,9-&gt;8,7,10,9-&gt;7,8,10,9(交换2次) <br />第二轮：7,8,10,9-&gt;7,8,10,9-&gt;7,8,10,9(交换0次) <br />第一轮：7,8,10,9-&gt;7,8,9,10(交换1次) <br />循环次数：6次 <br />交换次数：3次 <br /> <br />上面我们给出了程序段，现在我们分析它：这里，影响我们算法性能的主要部分是循环和交换， 显然，次数越多，性能就越差。从上面的程序我们可以看出循环的次数是固定的，为1+2+...+n-1。 <br />写成公式就是1/2*(n-1)*n。 <br />现在注意，我们给出O方法的定义： <br /> <br />&nbsp;&nbsp;若存在一常量K和起点n0，使当n&gt;=n0时，有f(n)&lt;=K*g(n),则f(n) = O(g(n))。（呵呵，不要说没学好数学呀，对于编程数学是非常重要的！！！） <br /> <br />现在我们来看1/2*(n-1)*n，当K=1/2，n0=1，g(n)=n*n时，1/2*(n-1)*n&lt;=1/2*n*n=K*g(n)。所以(n)=O(g(n))=O(n*n)。所以我们程序循环的复杂度为O(n*n)。 <br />再看交换。从程序后面所跟的表可以看到，两种情况的循环相同，交换不同。其实交换本身同数据源的有序程度有极大的关系，当数据处于倒序的情况时， 交换次数同循环一样（每次循环判断都会交换），复杂度为O(n*n)。当数据为正序，将不会有交换。复杂度为O(0)。乱序时处于中间状态。正是由于这样 的原因，我们通常都是通过循环次数来对比算法。 <br /> <br /> <br />2.交换法： <br />交换法的程序最清晰简单，每次用当前的元素一一的同其后的元素比较并交换。 <br />#include &lt;iostream.h&gt; <br />void ExchangeSort(int* pData,int Count) <br />{ <br />&nbsp;&nbsp;int iTemp; <br />&nbsp;&nbsp;for(int i=0;i&lt;Count-1;i++) <br />&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;for(int j=i+1;j&lt;Count;j++) <br />&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(pData[j]&lt;pData[i]) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iTemp = pData[i]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData[i] = pData[j]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData[j] = iTemp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;} <br />} <br /> <br />void main() <br />{ <br />&nbsp;&nbsp;int data[] = {10,9,8,7,6,5,4}; <br />&nbsp;&nbsp;ExchangeSort(data,7); <br />&nbsp;&nbsp;for (int i=0;i&lt;7;i++) <br />&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;data[i]&lt;&lt;" "; <br />&nbsp;&nbsp;cout&lt;&lt;"\n"; <br />} <br />倒序(最糟情况) <br />第一轮：10,9,8,7-&gt;9,10,8,7-&gt;8,10,9,7-&gt;7,10,9,8(交换3次) <br />第二轮：7,10,9,8-&gt;7,9,10,8-&gt;7,8,10,9(交换2次) <br />第一轮：7,8,10,9-&gt;7,8,9,10(交换1次) <br />循环次数：6次 <br />交换次数：6次 <br /> <br />其他： <br />第一轮：8,10,7,9-&gt;8,10,7,9-&gt;7,10,8,9-&gt;7,10,8,9(交换1次) <br />第二轮：7,10,8,9-&gt;7,8,10,9-&gt;7,8,10,9(交换1次) <br />第一轮：7,8,10,9-&gt;7,8,9,10(交换1次) <br />循环次数：6次 <br />交换次数：3次 <br /> <br />从运行的表格来看，交换几乎和冒泡一样糟。事实确实如此。循环次数和冒泡一样也是1/2*(n-1)*n，所以算法的复杂度仍然是O(n*n)。由于我们无法给出所有的情况，所以只能直接告诉大家他们在交换上面也是一样的糟糕（在某些情况下稍好，在某些情况下稍差）。 <br /> <br />3.选择法： <br />现在我们终于可以看到一点希望：选择法，这种方法提高了一点性能（某些情况下） <br />这种方法类似我们人为的排序习惯：从数据中选择最小的同第一个值交换，在从省下的部分中选择最小的与第二个交换，这样往复下去。 <br />#include &lt;iostream.h&gt; <br />void SelectSort(int* pData,int Count) <br />{ <br />&nbsp;&nbsp;int iTemp; <br />&nbsp;&nbsp;int iPos; <br />&nbsp;&nbsp;for(int i=0;i&lt;Count-1;i++) <br />&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;iTemp = pData[i]; <br />&nbsp;&nbsp;&nbsp;&nbsp;iPos = i; <br />&nbsp;&nbsp;&nbsp;&nbsp;for(int j=i+1;j&lt;Count;j++) <br />&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(pData[j]&lt;iTemp) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iTemp = pData[j]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iPos = j; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;&nbsp;&nbsp;pData[iPos] = pData[i]; <br />&nbsp;&nbsp;&nbsp;&nbsp;pData[i] = iTemp; <br />&nbsp;&nbsp;} <br />} <br /> <br />void main() <br />{ <br />&nbsp;&nbsp;int data[] = {10,9,8,7,6,5,4}; <br />&nbsp;&nbsp;SelectSort(data,7); <br />&nbsp;&nbsp;for (int i=0;i&lt;7;i++) <br />&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;data[i]&lt;&lt;" "; <br />&nbsp;&nbsp;cout&lt;&lt;"\n"; <br />} <br />倒序(最糟情况) <br />第一轮：10,9,8,7-&gt;(iTemp=9)10,9,8,7-&gt;(iTemp=8)10,9,8,7-&gt;(iTemp=7)7,9,8,10(交换1次) <br />第二轮：7,9,8,10-&gt;7,9,8,10(iTemp=8)-&gt;(iTemp=8)7,8,9,10(交换1次) <br />第一轮：7,8,9,10-&gt;(iTemp=9)7,8,9,10(交换0次) <br />循环次数：6次 <br />交换次数：2次 <br /> <br />其他： <br />第一轮：8,10,7,9-&gt;(iTemp=8)8,10,7,9-&gt;(iTemp=7)8,10,7,9-&gt;(iTemp=7)7,10,8,9(交换1次) <br />第二轮：7,10,8,9-&gt;(iTemp=8)7,10,8,9-&gt;(iTemp=8)7,8,10,9(交换1次) <br />第一轮：7,8,10,9-&gt;(iTemp=9)7,8,9,10(交换1次) <br />循环次数：6次 <br />交换次数：3次 <br />遗憾的是算法需要的循环次数依然是1/2*(n-1)*n。所以算法复杂度为O(n*n)。 <br />我们来看他的交换。由于每次外层循环只产生一次交换（只有一个最小值）。所以f(n)&lt;=n <br />所以我们有f(n)=O(n)。<br />所以，在数据较乱的时候，可以减少一定的交换次数。 <br /> <br /> <br />4.插入法： <br />插入法较为复杂，它的基本工作原理是抽出牌，在前面的牌中寻找相应的位置插入，然后继续下一张 <br />#include &lt;iostream.h&gt; <br />void InsertSort(int* pData,int Count) <br />{ <br />&nbsp;&nbsp;int iTemp; <br />&nbsp;&nbsp;int iPos; <br />&nbsp;&nbsp;for(int i=1;i&lt;Count;i++) <br />&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;iTemp = pData[i]; <br />&nbsp;&nbsp;&nbsp;&nbsp;iPos = i-1; <br />&nbsp;&nbsp;&nbsp;&nbsp;while((iPos&gt;=0) &amp;&amp; (iTemp&lt;pData[iPos])) <br />&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData[iPos+1] = pData[iPos]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iPos--; <br />&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;&nbsp;&nbsp;pData[iPos+1] = iTemp; <br />&nbsp;&nbsp;} <br />} <br /> <br />void main() <br />{ <br />&nbsp;&nbsp;int data[] = {10,9,8,7,6,5,4}; <br />&nbsp;&nbsp;InsertSort(data,7); <br />&nbsp;&nbsp;for (int i=0;i&lt;7;i++) <br />&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;data[i]&lt;&lt;" "; <br />&nbsp;&nbsp;cout&lt;&lt;"\n"; <br />} <br /> <br />倒序(最糟情况) <br />第一轮：10,9,8,7-&gt;9,10,8,7(交换1次)(循环1次) <br />第二轮：9,10,8,7-&gt;8,9,10,7(交换1次)(循环2次) <br />第一轮：8,9,10,7-&gt;7,8,9,10(交换1次)(循环3次) <br />循环次数：6次 <br />交换次数：3次 <br /> <br />其他： <br />第一轮：8,10,7,9-&gt;8,10,7,9(交换0次)(循环1次) <br />第二轮：8,10,7,9-&gt;7,8,10,9(交换1次)(循环2次) <br />第一轮：7,8,10,9-&gt;7,8,9,10(交换1次)(循环1次) <br />循环次数：4次 <br />交换次数：2次 <br /> <br />上面结尾的行为分析事实上造成了一种假象，让我们认为这种算法是简单算法中最好的，其实不是，因为其循环次数虽然并不固定，我们仍可以使用O方 法。从上面的结果可以看出，循环的次数f(n)&lt;= 1/2*n*(n-1)&lt;=1/2*n*n。所以其复杂度仍为O(n*n)（这里说明一下，其实如果不是为了展示这些简单排序的不同，交换次数仍然 可以这样推导）。现在看交换，从外观上看，交换次数是O(n)（推导类似选择法），但我们每次要进行与内层循环相同次数的&#8216;=&#8217;操作。正常的一次交换我们 需要三次&#8216;=&#8217;，而这里显然多了一些，所以我们浪费了时间。 <br /> <br />最终，我个人认为，在简单排序算法中，选择法是最好的。 <br /> <br /> <br />二、高级排序算法： <br />高级排序算法中我们将只介绍这一种，同时也是目前我所知道（我看过的资料中）的最快的。 <br />它的工作看起来仍然象一个二叉树。首先我们选择一个中间值middle程序中我们使用数组中间值，然后把比它小的放在左边，大的放在右边（具体的实现是从两边找，找到一对后交换）。然后对两边分别使用这个过程（最容易的方法&#8212;&#8212;递归）。 <br /> <br />1.快速排序： <br />#include &lt;iostream.h&gt; <br /> <br />void run(int* pData,int left,int right) <br />{ <br />&nbsp;&nbsp;int i,j; <br />&nbsp;&nbsp;int middle,iTemp; <br />&nbsp;&nbsp;i = left; <br />&nbsp;&nbsp;j = right; <br />&nbsp;&nbsp;middle = pData[(left+right)/2];&nbsp;//求中间值 <br />&nbsp;&nbsp;do{ <br />&nbsp;&nbsp;&nbsp;&nbsp;while((pData[i]&lt;middle) &amp;&amp; (i&lt;right))//从左扫描大于中值的数 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i++;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br />&nbsp;&nbsp;&nbsp;&nbsp;while((pData[j]&gt;middle) &amp;&amp; (j&gt;left))//从右扫描大于中值的数 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j--; <br />&nbsp;&nbsp;&nbsp;&nbsp;if(i&lt;=j)//找到了一对值 <br />&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//交换 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iTemp = pData[i]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData[i] = pData[j]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData[j] = iTemp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i++; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j--; <br />&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;}while(i&lt;=j);//如果两边扫描的下标交错，就停止（完成一次） <br /> <br />&nbsp;&nbsp;//当左边部分有值(left&lt;j)，递归左半边 <br />&nbsp;&nbsp;if(left&lt;j) <br />&nbsp;&nbsp;&nbsp;&nbsp;run(pData,left,j); <br />&nbsp;&nbsp;//当右边部分有值(right&gt;i)，递归右半边 <br />&nbsp;&nbsp;if(right&gt;i) <br />&nbsp;&nbsp;&nbsp;&nbsp;run(pData,i,right); <br />} <br /> <br />void QuickSort(int* pData,int Count) <br />{ <br />&nbsp;&nbsp;run(pData,0,Count-1); <br />} <br /> <br />void main() <br />{ <br />&nbsp;&nbsp;int data[] = {10,9,8,7,6,5,4}; <br />&nbsp;&nbsp;QuickSort(data,7); <br />&nbsp;&nbsp;for (int i=0;i&lt;7;i++) <br />&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;data[i]&lt;&lt;" "; <br />&nbsp;&nbsp;cout&lt;&lt;"\n"; <br />} <br /> <br />这里我没有给出行为的分析，因为这个很简单，我们直接来分析算法：首先我们考虑最理想的情况 <br />1.数组的大小是2的幂，这样分下去始终可以被2整除。假设为2的k次方，即k=log2(n)。 <br />2.每次我们选择的值刚好是中间值，这样，数组才可以被等分。 <br />第一层递归，循环n次，第二层循环2*(n/2)...... <br />所以共有n+2(n/2)+4(n/4)+...+n*(n/n) = n+n+n+...+n=k*n=log2(n)*n <br />所以算法复杂度为O(log2(n)*n) <br />其他的情况只会比这种情况差，最差的情况是每次选择到的middle都是最小值或最大值，那么他将变成交换法（由于使用了递归，情况更糟）。但是你认为这种情况发生的几率有多大？？呵呵，你完全不必担心这个问题。实践证明，大多数的情况，快速排序总是最好的。 <br />如果你担心这个问题，你可以使用堆排序，这是一种稳定的O(log2(n)*n)算法，但是通常情况下速度要慢 <br />于快速排序（因为要重组堆）。 <br /> <br />三、其他排序 <br />1.双向冒泡： <br />通常的冒泡是单向的，而这里是双向的，也就是说还要进行反向的工作。 <br />代码看起来复杂，仔细理一下就明白了，是一个来回震荡的方式。 <br />写这段代码的作者认为这样可以在冒泡的基础上减少一些交换（我不这么认为，也许我错了）。 <br />反正我认为这是一段有趣的代码，值得一看。 <br />#include &lt;iostream.h&gt; <br />void Bubble2Sort(int* pData,int Count) <br />{ <br />&nbsp;&nbsp;int iTemp; <br />&nbsp;&nbsp;int left = 1; <br />&nbsp;&nbsp;int right =Count -1; <br />&nbsp;&nbsp;int t; <br />&nbsp;&nbsp;do <br />&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;//正向的部分 <br />&nbsp;&nbsp;&nbsp;&nbsp;for(int i=right;i&gt;=left;i--) <br />&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(pData[i]&lt;pData[i-1]) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iTemp = pData[i]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData[i] = pData[i-1]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData[i-1] = iTemp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t = i;  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;&nbsp;&nbsp;left = t+1; <br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;//反向的部分 <br />&nbsp;&nbsp;&nbsp;&nbsp;for(i=left;i&lt;right+1;i++) <br />&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(pData[i]&lt;pData[i-1]) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iTemp = pData[i]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData[i] = pData[i-1]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData[i-1] = iTemp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t = i;  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;&nbsp;&nbsp;right = t-1; <br />&nbsp;&nbsp;}while(left&lt;=right); <br />} <br /> <br />void main() <br />{ <br />&nbsp;&nbsp;int data[] = {10,9,8,7,6,5,4}; <br />&nbsp;&nbsp;Bubble2Sort(data,7); <br />&nbsp;&nbsp;for (int i=0;i&lt;7;i++) <br />&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;data[i]&lt;&lt;" "; <br />&nbsp;&nbsp;cout&lt;&lt;"\n"; <br />} <br /> <br /> <br />2.SHELL排序 <br />这个排序非常复杂，看了程序就知道了。 <br />首先需要一个递减的步长，这里我们使用的是9、5、3、1（最后的步长必须是1）。 <br />工作原理是首先对相隔9-1个元素的所有内容排序，然后再使用同样的方法对相隔5-1个元素的排序以次类推。 <br />#include &lt;iostream.h&gt; <br />void ShellSort(int* pData,int Count) <br />{ <br />&nbsp;&nbsp;int step[4]; <br />&nbsp;&nbsp;step[0] = 9; <br />&nbsp;&nbsp;step[1] = 5; <br />&nbsp;&nbsp;step[2] = 3; <br />&nbsp;&nbsp;step[3] = 1; <br /> <br />&nbsp;&nbsp;int iTemp; <br />&nbsp;&nbsp;int k,s,w; <br />&nbsp;&nbsp;for(int i=0;i&lt;4;i++) <br />&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;k = step[i]; <br />&nbsp;&nbsp;&nbsp;&nbsp;s = -k; <br />&nbsp;&nbsp;&nbsp;&nbsp;for(int j=k;j&lt;Count;j++) <br />&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iTemp = pData[j]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;w = j-k;//求上step个元素的下标 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(s ==0) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = -k; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s++; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData[s] = iTemp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while((iTemp&lt;pData[w]) &amp;&amp; (w&gt;=0) &amp;&amp; (w&lt;=Count)) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData[w+k] = pData[w]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;w = w-k; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData[w+k] = iTemp; <br />&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;} <br />} <br /> <br />void main() <br />{ <br />&nbsp;&nbsp;int data[] = {10,9,8,7,6,5,4,3,2,1,-10,-1}; <br />&nbsp;&nbsp;ShellSort(data,12); <br />&nbsp;&nbsp;for (int i=0;i&lt;12;i++) <br />&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;data[i]&lt;&lt;" "; <br />&nbsp;&nbsp;cout&lt;&lt;"\n"; <br />} <br />呵呵，程序看起来有些头疼。不过也不是很难，把s==0的块去掉就轻松多了，这里是避免使用0步长造成程序异常而写的代码。这个代码我认为很值得一看。 <br />这个算法的得名是因为其发明者的名字D.L.SHELL。依照参考资料上的说法：&#8220;由于复杂的数学原因避免使用2的幂次步长，它能降低算法效率。&#8221;另外算法的复杂度为n的1.2次幂。同样因为非常复杂并&#8220;超出本书讨论范围&#8221;的原因（我也不知道过程），我们只有结果了。 <br /> <br />最后，希望大家愉快的编程。有什么意见，给我提吧！ 		 		 		 		 		 </div><img src ="http://www.cppblog.com/softko/aggbug/148828.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/softko/" target="_blank">eircQ</a> 2011-06-17 08:09 <a href="http://www.cppblog.com/softko/archive/2011/06/17/148828.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hash 算法及其应用(转)</title><link>http://www.cppblog.com/softko/archive/2010/12/02/135309.html</link><dc:creator>eircQ</dc:creator><author>eircQ</author><pubDate>Thu, 02 Dec 2010 15:08:00 GMT</pubDate><guid>http://www.cppblog.com/softko/archive/2010/12/02/135309.html</guid><wfw:comment>http://www.cppblog.com/softko/comments/135309.html</wfw:comment><comments>http://www.cppblog.com/softko/archive/2010/12/02/135309.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/softko/comments/commentRss/135309.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/softko/services/trackbacks/135309.html</trackback:ping><description><![CDATA[<table width="97%" align="center" style="color: rgb(51, 51, 51); font-family: tahoma, 宋体; font-size: 12px; "><tbody><tr><td width="140" style="font-size: 12px; word-wrap: break-word; ">期：2004-07-30]</td><td align="center" style="font-size: 12px; word-wrap: break-word; ">来源：<a href="http://dev.csdn.net/develop/article/30/30184.shtm" target="_blank" style="color: rgb(65, 81, 154); text-decoration: none; ">CSDN</a>&nbsp; 作者：</td><td width="160" align="right" style="font-size: 12px; word-wrap: break-word; ">[字体：<a href="http://www.iwms.net/n923c43.aspx" style="color: rgb(65, 81, 154); text-decoration: none; ">大</a>&nbsp;<a href="http://www.iwms.net/n923c43.aspx" style="color: rgb(65, 81, 154); text-decoration: none; ">中</a>&nbsp;<a href="http://www.iwms.net/n923c43.aspx" style="color: rgb(65, 81, 154); text-decoration: none; ">小</a>]</td></tr></tbody></table><div id="content" style="font-size: 14px; word-wrap: break-word; font-family: tahoma, 宋体; line-height: 1.6; margin-top: 20px; margin-right: auto; margin-bottom: 20px; margin-left: auto; width: 659px; overflow-x: hidden; word-break: break-all; color: rgb(51, 51, 51); "><p>---------------&nbsp;<br>什么是 Hash&nbsp;<br>Hash 的重要特性&nbsp;<br>Hash 函数的实现&nbsp;<br>主要的 Hash 算法&nbsp;<br>Hash 算法的安全问题&nbsp;<br>Hash 算法的应用&nbsp;<br>结 论&nbsp;<br>---------------</p><p><br>Hash，一般翻译做&#8220;散列&#8221;，也有直接音译为"哈希"的，就是把任意长度的输入（又叫做预映射， pre-image），通过散列算法，变换成固定长度的输出，该输出就是散列值。这种转换是一种压缩映射，也就是，散列值的空间通常远小于输入的空间，不同的输入可能会散列成相同的输出，而不可能从散列值来唯一的确定输入值。</p><p>数学表述为：h = H(M) ，其中H( )--单向散列函数，M--任意长度明文，h--固定长度散列值。</p><p>&#160;</p><p>在信息安全领域中应用的Hash算法，还需要满足其他关键特性：</p><p>第一当然是单向性(one-way)，从预映射，能够简单迅速的得到散列值，而在计算上不可能构造一个预映射，使其散列结果等于某个特定的散列值，即构造相应的M=H-1(h)不可行。这样，散列值就能在统计上唯一的表征输入值，因此，密码学上的 Hash 又被称为"消息摘要(message digest)"，就是要求能方便的将"消息"进行"摘要"，但在"摘要"中无法得到比"摘要"本身更多的关于"消息"的信息。</p><p>第二是抗冲突性(collision-resistant)，即在统计上无法产生2个散列值相同的预映射。给定M，计算上无法找到M'，满足H(M)=H(M') ，此谓弱抗冲突性；计算上也难以寻找一对任意的M和M'，使满足H(M)=H(M') ，此谓强抗冲突性。要求"强抗冲突性"主要是为了防范所谓"生日攻击(birthday attack)"，在一个10人的团体中，你能找到和你生日相同的人的概率是2.4%，而在同一团体中，有2人生日相同的概率是11.7%。类似的，当预映射的空间很大的情况下，算法必须有足够的强度来保证不能轻易找到"相同生日"的人。</p><p>第三是映射分布均匀性和差分分布均匀性，散列结果中，为 0 的 bit 和为 1 的 bit ，其总数应该大致相等；输入中一个 bit 的变化，散列结果中将有一半以上的 bit 改变，这又叫做"雪崩效应(avalanche effect)"；要实现使散列结果中出现 1bit 的变化，则输入中至少有一半以上的 bit 必须发生变化。其实质是必须使输入中每一个 bit 的信息，尽量均匀的反映到输出的每一个 bit 上去；输出中的每一个 bit，都是输入中尽可能多 bit 的信息一起作用的结果。</p><p>&#160;</p><p>Damgard 和 Merkle 定义了所谓&#8220;压缩函数(compression function)&#8221;，就是将一个固定长度输入，变换成较短的固定长度的输出，这对密码学实践上 Hash 函数的设计产生了很大的影响。Hash函数就是被设计为基于通过特定压缩函数的不断重复&#8220;压缩&#8221;输入的分组和前一次压缩处理的结果的过程，直到整个消息都被压缩完毕，最后的输出作为整个消息的散列值。尽管还缺乏严格的证明，但绝大多数业界的研究者都同意，如果压缩函数是安全的，那么以上述形式散列任意长度的消息也将是安全的。这就是所谓 Damgard/Merkle 结构：</p><p>在下图中，任意长度的消息被分拆成符合压缩函数输入要求的分组，最后一个分组可能需要在末尾添上特定的填充字节，这些分组将被顺序处理，除了第一个消息分组将与散列初始化值一起作为压缩函数的输入外，当前分组将和前一个分组的压缩函数输出一起被作为这一次压缩的输入，而其输出又将被作为下一个分组压缩函数输入的一部分，直到最后一个压缩函数的输出，将被作为整个消息散列的结果。</p><p>&#160;</p><p>&#160;</p><p>MD5 和 SHA1 可以说是目前应用最广泛的Hash算法，而它们都是以 MD4 为基础设计的。</p><p>1) MD4&nbsp;<br>MD4(RFC 1320)是 MIT 的 Ronald L. Rivest 在 1990 年设计的，MD 是 Message Digest 的缩写。它适用在32位字长的处理器上用高速软件实现--它是基于 32 位操作数的位操作来实现的。它的安全性不像RSA那样基于数学假设，尽管 Den Boer、Bosselaers 和 Dobbertin 很快就用分析和差分成功的攻击了它3轮变换中的 2 轮，证明了它并不像期望的那样安全，但它的整个算法并没有真正被破解过，Rivest 也很快进行了改进。</p><p>下面是一些MD4散列结果的例子：</p><p>MD4 ("") = 31d6cfe0d16ae931b73c59d7e0c089c0&nbsp;<br>MD4 ("a") = bde52cb31de33e46245e05fbdbd6fb24&nbsp;<br>MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d&nbsp;<br>MD4 ("message digest") = d9130a8164549fe818874806e1c7014b&nbsp;<br>MD4 ("abcdefghijklmnopqrstuvwxyz") = d79e1c308aa5bbcdeea8ed63df412da9&nbsp;<br>MD4 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = 043f8582f241db351ce627e153e7f0e4&nbsp;<br>MD4 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = e33b4ddc9c38f2199c3e7b164fcc0536</p><p><br>2) MD5&nbsp;<br>MD5(RFC 1321)是 Rivest 于1991年对MD4的改进版本。它对输入仍以512位分组，其输出是4个32位字的级联，与 MD4 相同。它较MD4所做的改进是：</p><p>1) 加入了第四轮&nbsp;<br>2) 每一步都有唯一的加法常数；&nbsp;<br>3) 第二轮中的G函数从((X ∧ Y) ∨ (X ∧ Z) ∨ (Y ∧ Z)) 变为 ((X ∧ Z) ∨ (Y ∧ ～Z))以减小其对称性；&nbsp;<br>4) 每一步都加入了前一步的结果，以加快"雪崩效应"；&nbsp;<br>5) 改变了第2轮和第3轮中访问输入子分组的顺序，减小了形式的相似程度；&nbsp;<br>6) 近似优化了每轮的循环左移位移量，以期加快"雪崩效应"，各轮的循环左移都不同。&nbsp;<br>尽管MD5比MD4来得复杂，并且速度较之要慢一点，但更安全，在抗分析和抗差分方面表现更好。</p><p>消息首先被拆成若干个512位的分组，其中最后512位一个分组是&#8220;消息尾+填充字节(100&#8230;0)+64 位消息长度&#8221;，以确保对于不同长度的消息，该分组不相同。64位消息长度的限制导致了MD5安全的输入长度必须小于264bit，因为大于64位的长度信息将被忽略。而4个32位寄存器字初始化为A=0x01234567，B=0x89abcdef，C=0xfedcba98，D=0x76543210，它们将始终参与运算并形成最终的散列结果。</p><p>接着各个512位消息分组以16个32位字的形式进入算法的主循环，512位消息分组的个数据决定了循环的次数。主循环有4轮，每轮分别用到了非线性函数</p><p>F(X, Y, Z) = (X ∧ Y) ∨ (～X ∧ Z)&nbsp;<br>G(X, Y, Z) = (X ∧ Z) ∨ (Y ∧ ～Z)&nbsp;<br>H(X, Y, Z) =X &#8853; Y &#8853; Z&nbsp;<br>I(X, Y, Z) = X &#8853; (Y ∨ ～Z)&nbsp;<br>这4轮变换是对进入主循环的512位消息分组的16个32位字分别进行如下操作：将A、B、C、D的副本a、b、c、d中的3个经F、G、H、I运算后的结果与第4个相加，再加上32位字和一个32位字的加法常数，并将所得之值循环左移若干位，最后将所得结果加上a、b、c、d之一，并回送至ABCD，由此完成一次循环。</p><p>所用的加法常数由这样一张表T[i]来定义，其中i为1&#8230;64，T[i]是i的正弦绝对值之4294967296次方的整数部分，这样做是为了通过正弦函数和幂函数来进一步消除变换中的线性性。</p><p>当所有512位分组都运算完毕后，ABCD的级联将被输出为MD5散列的结果。下面是一些MD5散列结果的例子：</p><p>MD5 ("") = d41d8cd98f00b204e9800998ecf8427e&nbsp;<br>MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661&nbsp;<br>MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72&nbsp;<br>MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0&nbsp;<br>MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b&nbsp;<br>MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = d174ab98d277d9f5a5611c2c9f419d9f&nbsp;<br>MD5 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 57edf4a22be3c955ac49da2e2107b67a&nbsp;<br>参考相应RFC文档可以得到MD4、MD5算法的详细描述和算法的C源代码。</p><p>3) SHA1 及其他&nbsp;<br>SHA1是由NIST NSA设计为同DSA一起使用的，访问http://www.itl.nist.gov/fipspubs可以得到它的详细规范--[/url]"FIPS PUB 180-1 SECURE HASH STANDARD"。它对长度小于264的输入，产生长度为160bit的散列值，因此抗穷举(brute-force)性更好。SHA-1 设计时基于和MD4相同原理,并且模仿了该算法。因为它将产生160bit的散列值，因此它有5个参与运算的32位寄存器字，消息分组和填充方式与MD5相同，主循环也同样是4轮，但每轮进行20次操作，非线性运算、移位和加法运算也与MD5类似，但非线性函数、加法常数和循环左移操作的设计有一些区别，可以参考上面提到的规范来了解这些细节。下面是一些SHA1散列结果的例子：</p><p>SHA1 ("abc") = a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d&nbsp;<br>SHA1 ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 84983e44 1c3bd26e baae4aa1 f95129e5 e54670f1&nbsp;<br>其他一些知名的Hash算法还有MD2、N-Hash、RIPE-MD、HAVAL等等。上面提到的这些都属于"纯"Hash算法。还有另2类Hash算法，一类就是基于对称分组算法的单向散列算法，典型的例子是基于DES的所谓Davies-Meyer算法，另外还有经IDEA改进的Davies-Meyer算法，它们两者目前都被认为是安全的算法。另一类是基于模运算/离散对数的，也就是基于公开密钥算法的，但因为其运算开销太大，而缺乏很好的应用前景。</p><p>&#160;</p><p>没有通过分析和差分攻击考验的算法，大多都已经夭折在实验室里了，因此，如果目前流行的Hash算法能完全符合密码学意义上的单向性和抗冲突性，就保证了只有穷举，才是破坏Hash运算安全特性的唯一方法。为了对抗弱抗冲突性，我们可能要穷举个数和散列值空间长度一样大的输入，即尝试2^128或2^160个不同的输入，目前一台高档个人电脑可能需要10^25年才能完成这一艰巨的工作，即使是最高端的并行系统，这也不是在几千年里的干得完的事。而因为"生日攻击"有效的降低了需要穷举的空间，将其降低为大约1.2*2^64或1.2*2^80，所以，强抗冲突性是决定Hash算法安全性的关键。</p><p>在NIST新的 Advanced Encryption Standard (AES)中，使用了长度为128、192、256bit 的密钥，因此相应的设计了 SHA256、SHA384、SHA512，它们将提供更好的安全性。</p><p>&#160;</p><p>Hash算法在信息安全方面的应用主要体现在以下的3个方面：</p><p>1) 文件校验&nbsp;<br>我们比较熟悉的校验算法有奇偶校验和CRC校验，这2种校验并没有抗数据篡改的能力，它们一定程度上能检测并纠正数据传输中的信道误码，但却不能防止对数据的恶意破坏。</p><p>MD5 Hash算法的"数字指纹"特性，使它成为目前应用最广泛的一种文件完整性校验和(Checksum)算法，不少Unix系统有提供计算md5 checksum的命令。它常被用在下面的2种情况下：</p><p>第一是文件传送后的校验，将得到的目标文件计算 md5 checksum，与源文件的md5 checksum 比对，由两者 md5 checksum 的一致性，可以从统计上保证2个文件的每一个码元也是完全相同的。这可以检验文件传输过程中是否出现错误，更重要的是可以保证文件在传输过程中未被恶意篡改。一个很典型的应用是ftp服务，用户可以用来保证多次断点续传，特别是从镜像站点下载的文件的正确性。</p><p>更出色的解决方法是所谓的代码签名，文件的提供者在提供文件的同时，提供对文件Hash值用自己的代码签名密钥进行数字签名的值，及自己的代码签名证书。文件的接受者不仅能验证文件的完整性，还可以依据自己对证书签发者和证书拥有者的信任程度，决定是否接受该文件。浏览器在下载运行插件和java小程序时，使用的就是这样的模式。</p><p>第二是用作保存二进制文件系统的数字指纹，以便检测文件系统是否未经允许的被修改。不少系统管理/系统安全软件都提供这一文件系统完整性评估的功能，在系统初始安装完毕后，建立对文件系统的基础校验和数据库，因为散列校验和的长度很小，它们可以方便的被存放在容量很小的存储介质上。此后，可以定期或根据需要，再次计算文件系统的校验和，一旦发现与原来保存的值有不匹配，说明该文件已经被非法修改，或者是被病毒感染，或者被木马程序替代。TripWire就提供了一个此类应用的典型例子。</p><p>更完美的方法是使用"MAC"。"MAC" 是一个与Hash密切相关的名词，即信息鉴权码(Message Authority Code)。它是与密钥相关的Hash值，必须拥有该密钥才能检验该Hash值。文件系统的数字指纹也许会被保存在不可信任的介质上，只对拥有该密钥者提供可鉴别性。并且在文件的数字指纹有可能需要被修改的情况下，只有密钥的拥有者可以计算出新的散列值，而企图破坏文件完整性者却不能得逞。</p><p>2) 数字签名&nbsp;<br>Hash 算法也是现代密码体系中的一个重要组成部分。由于非对称算法的运算速度较慢，所以在数字签名协议中，单向散列函数扮演了一个重要的角色。</p><p>在这种签名协议中，双方必须事先协商好双方都支持的Hash函数和签名算法。</p><p>签名方先对该数据文件进行计算其散列值，然后再对很短的散列值结果--如Md5是16个字节，SHA1是20字节，用非对称算法进行数字签名操作。对方在验证签名时，也是先对该数据文件进行计算其散列值，然后再用非对称算法验证数字签名。</p><p>对 Hash 值，又称"数字摘要"进行数字签名，在统计上可以认为与对文件本身进行数字签名是等效的。而且这样的协议还有其他的优点：</p><p>首先，数据文件本身可以同它的散列值分开保存，签名验证也可以脱离数据文件本身的存在而进行。</p><p>再者，有些情况下签名密钥可能与解密密钥是同一个，也就是说，如果对一个数据文件签名，与对其进行非对称的解密操作是相同的操作，这是相当危险的，恶意的破坏者可能将一个试图骗你将其解密的文件，充当一个要求你签名的文件发送给你。因此，在对任何数据文件进行数字签名时，只有对其Hash值进行签名才是安全的。</p><p>3) 鉴权协议&nbsp;<br>如下的鉴权协议又被称作"挑战--认证模式：在传输信道是可被侦听，但不可被篡改的情况下，这是一种简单而安全的方法。</p><p>需要鉴权的一方，向将被鉴权的一方发送随机串（&#8220;挑战&#8221;），被鉴权方将该随机串和自己的鉴权口令字一起进行 Hash 运算后，返还鉴权方，鉴权方将收到的Hash值与在己端用该随机串和对方的鉴权口令字进行 Hash 运算的结果相比较（&#8220;认证&#8221;），如相同，则可在统计上认为对方拥有该口令字，即通过鉴权。</p><p>POP3协议中就有这一应用的典型例子：</p><p>S: +OK POP3 server ready &lt;1896.697170952@dbc.mtview.ca.us&gt;&nbsp;<br>C: APOP mrose c4c9334bac560ecc979e58001b3e22fb&nbsp;<br>S: +OK maildrop has 1 message (369 octets)&nbsp;<br>在上面的一段POP3协议会话中，双方都共享的对称密钥（鉴权口令字）是tanstaaf，服务器发出的挑战是&lt;1896.697170952@dbc.mtview.ca.us&gt;，客户端对挑战的应答是MD5("&lt;1896.697170952@dbc.mtview.ca.us&gt;tanstaaf") = c4c9334bac560ecc979e58001b3e22fb，这个正确的应答使其通过了认证。</p><p>&#160;</p><p>散列算法长期以来一直在计算机科学中大量应用，随着现代密码学的发展，单向散列函数已经成为信息安全领域中一个重要的结构模块，我们有理由深入研究其设计理论和应用方法。</p></div>
<img src ="http://www.cppblog.com/softko/aggbug/135309.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/softko/" target="_blank">eircQ</a> 2010-12-02 23:08 <a href="http://www.cppblog.com/softko/archive/2010/12/02/135309.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++随机数生成方法（转载)</title><link>http://www.cppblog.com/softko/archive/2010/12/02/135228.html</link><dc:creator>eircQ</dc:creator><author>eircQ</author><pubDate>Thu, 02 Dec 2010 00:42:00 GMT</pubDate><guid>http://www.cppblog.com/softko/archive/2010/12/02/135228.html</guid><wfw:comment>http://www.cppblog.com/softko/comments/135228.html</wfw:comment><comments>http://www.cppblog.com/softko/archive/2010/12/02/135228.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/softko/comments/commentRss/135228.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/softko/services/trackbacks/135228.html</trackback:ping><description><![CDATA[<div class="cnt" id="blog_text">
<div style="font-size: 16px;">
<p>原文 http://www.cnblogs.com/finallyliuyu/archive/2010/10/11/1848130.html<br></p>
<p>一、C++中不能使用random()函数</p>
<p>==================================================================================</p>
<p>本文由青松原创并依GPL-V2及其后续版本发放，转载请注明出处且应包含本行声明。</p>
<p>C++中常用rand()函数生成随机数，但严格意义上来讲生成的只是伪随机数（pseudo-random integral
number）。生成随机数时需要我们指定一个种子，如果在程序内循环，那么下一次生成随机数时调用上一次的结果作为种子。但如果分两次执行程序，那么由
于种子相同，生成的&#8220;随机数&#8221;也是相同的。</p>
<p>在工程应用时，我们一般将系统当前时间(Unix时间)作为种子，这样生成的随机数更接近于实际意义上的随机数。给一下例程如下：</p>
<p>#include &lt;iostream&gt;<br>#include &lt;ctime&gt;<br>#include &lt;cstdlib&gt;<br>using namespace std;</p>
<p>int main()<br>{<br>&nbsp;&nbsp;&nbsp; double random(double,double);<br>&nbsp;&nbsp;&nbsp; srand(unsigned(time(0)));<br>&nbsp;&nbsp;&nbsp; for(int icnt = 0; icnt != 10; ++icnt)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "No." &lt;&lt; icnt+1 &lt;&lt; ": " &lt;&lt; int(random(0,10))&lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp; return 0;<br>}</p>
<p>double random(double start, double end)<br>{<br>&nbsp;&nbsp;&nbsp; return start+(end-start)*rand()/(RAND_MAX + 1.0);<br>}<br>/* 运行结果<br>* No.1: 3<br>* No.2: 9<br>* No.3: 0<br>* No.4: 9<br>* No.5: 5<br>* No.6: 6<br>* No.7: 9<br>* No.8: 2<br>* No.9: 9<br>* No.10: 6<br>*/<br>利用这种方法能不能得到完全意义上的随机数呢？似乎9有点多哦？却没有1,4,7？！我们来做一个概率实验，生成1000万个随机数，看0-9这10个数出现的频率是不是大致相同的。程序如下：<br>#include &lt;iostream&gt;<br>#include &lt;ctime&gt;<br>#include &lt;cstdlib&gt;<br>#include &lt;iomanip&gt;<br>using namespace std;</p>
<p>int main()<br>{<br>&nbsp;&nbsp;&nbsp; double random(double,double);<br>&nbsp;&nbsp;&nbsp; int a[10] = {0};<br>&nbsp;&nbsp;&nbsp; const int Gen_max = 10000000;<br>&nbsp;&nbsp;&nbsp; srand(unsigned(time(0)));<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; for(int icnt = 0; icnt != Gen_max; ++icnt)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch(int(random(0,10)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 0: a[0]++; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 1: a[1]++; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 2: a[2]++; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 3: a[3]++; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 4: a[4]++; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 5: a[5]++; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 6: a[6]++; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 7: a[7]++; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 8: a[8]++; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 9: a[9]++; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default: cerr &lt;&lt; "Error!" &lt;&lt; endl; exit(-1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; for(int icnt = 0; icnt != 10; ++icnt)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cout &lt;&lt; icnt &lt;&lt; ": " &lt;&lt; setw(6) &lt;&lt;
setiosflags(ios::fixed) &lt;&lt; setprecision(2) &lt;&lt;
double(a[icnt])/Gen_max*100 &lt;&lt; "%" &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; return 0;<br>}</p>
<p>double random(double start, double end)<br>{<br>&nbsp;&nbsp;&nbsp; return start+(end-start)*rand()/(RAND_MAX + 1.0);<br>}<br>/* 运行结果<br>* 0: 10.01%<br>* 1:&nbsp;&nbsp; 9.99%<br>* 2:&nbsp;&nbsp; 9.99%<br>* 3:&nbsp;&nbsp; 9.99%<br>* 4:&nbsp;&nbsp; 9.98%<br>* 5: 10.01%<br>* 6: 10.02%<br>* 7: 10.01%<br>* 8: 10.01%<br>* 9:&nbsp;&nbsp; 9.99%<br>*/<br>可知用这种方法得到的随机数是满足统计规律的。</p>
<p>另：在Linux下利用GCC编译程序，即使我执行了1000000次运算，是否将random函数定义了inline函数似乎对程序没有任何影响，有理由相信，GCC已经为我们做了优化。但是冥冥之中我又记得要做inline优化得加O3才行...</p>
<p>不行，于是我们把循环次数改为10亿次，用time命令查看执行时间：<br><a  href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#99;&#104;&#105;&#110;&#115;&#117;&#110;&#103;&#64;&#103;&#101;&#110;&#116;&#111;&#111;" target="_blank">chinsung@gentoo</a> ~/workspace/test/Debug $ time ./test <br>0: 10.00%<br>1: 10.00%<br>2: 10.00%<br>3: 10.00%<br>4: 10.00%<br>5: 10.00%<br>6: 10.00%<br>7: 10.00%<br>8: 10.00%<br>9: 10.00%</p>
<p>real&nbsp;&nbsp;&nbsp; 2m7.768s<br>user&nbsp;&nbsp;&nbsp; 2m4.405s<br>sys&nbsp;&nbsp;&nbsp;&nbsp; 0m0.038s<br><a  href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#99;&#104;&#105;&#110;&#115;&#117;&#110;&#103;&#64;&#103;&#101;&#110;&#116;&#111;&#111;" target="_blank">chinsung@gentoo</a> ~/workspace/test/Debug $ time ./test <br>0: 10.00%<br>1: 10.00%<br>2: 10.00%<br>3: 10.00%<br>4: 10.00%<br>5: 10.00%<br>6: 10.00%<br>7: 10.00%<br>8: 10.00%<br>9: 10.00%</p>
<p>real&nbsp;&nbsp;&nbsp; 2m7.269s<br>user&nbsp;&nbsp;&nbsp; 2m4.077s<br>sys&nbsp;&nbsp;&nbsp;&nbsp; 0m0.025s</p>
<p>前一次为进行inline优化的情形，后一次为没有作inline优化的情形，两次结果相差不大，甚至各项指标后者还要好一些，不知是何缘由...</p>
<p>=================================================================================</p>
<p><br>&nbsp;&nbsp;&nbsp;&nbsp; random函数不是ANSI C标准，不能在gcc,vc等编译器下编译通过。
可改用C++下的rand函数来实现。&nbsp;&nbsp;&nbsp;&nbsp; 1、C++标准函数库提供一随机数生成器rand，返回0－RAND_MAX之间均匀分布的伪随机整数。
RAND_MAX必须至少为32767。rand()函数不接受参数，默认以1为种子（即起始值）。
随机数生成器总是以相同的种子开始，所以形成的伪随机数列也相同，失去了随机意义。（但这样便于程序调试） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、C++中另一函数srand（），可以指定不同的数（无符号整数变元）为种子。但是如果种子相同，伪随机数列也相同。一个办法是让用户输入种子，但是仍然不理想。 <br>&nbsp;&nbsp;&nbsp;&nbsp; 3、 比较理想的是用变化的数，比如时间来作为随机数生成器的种子。 time的值每时每刻都不同。所以种子不同，所以，产生的随机数也不同。 <br>// C++随机函数（VC program） <br>#include &lt;stdio.h&gt; <br>#include &lt;iostream&gt; <br>#include &lt;time.h&gt; <br>using namespace std; <br>#define MAX 100 <br>int main(int argc, char* argv[]) <br>{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; srand( (unsigned)time( NULL ) );//srand()函数产生一个以当前时间开始的随机种子.应该放在for等循环语句前面 不然要很长时间等待 <br>　　 for (int i=0;i&lt;10;i++) <br>　　 cout&lt;&lt;rand()%MAX&lt;&lt;endl;//MAX为最大值，其随机域为0~MAX-1<br>　　 return 0; <br>} <br>二、rand()的用法 <br>&nbsp;&nbsp;&nbsp;&nbsp; rand()不需要参数，它会返回一个从0到最大随机数的任意整数，最大随机数的大小通常是固定的一个大整数。 这样，如果你要产生0~10的10个整数，可以表达为： <br>　　int N = rand() % 11; <br>&nbsp;&nbsp;&nbsp;&nbsp; 这样，N的值就是一个0~10的随机数，如果要产生1~10，则是这样： <br>　　int N = 1 + rand() % 10; <br>　　总结来说，可以表示为： <br>　　a + rand() % n<br>&nbsp;&nbsp;&nbsp;&nbsp;
其中的a是起始值，n是整数的范围。 　　a + rand() % (b-a+1)
就表示　ａ～ｂ之间的一个随机数若要0~1的小数，则可以先取得0~10的整数，然后均除以10即可得到随机到十分位的10个随机小数，若要得到随机到百
分位的随机小数，则需要先得到0~100的10个整数，然后均除以100，其它情况依此类推。 <br>&nbsp;&nbsp;&nbsp;&nbsp; 通常rand()产生的随机数在每次运行的时候都是与上一次相同的，这是有意这样设计的，是为了便于程序的调试。若要产生每次不同的随机数，可以使用srand( seed )函数进行随机化，随着seed的不同，就能够产生不同的随机数。 <br>&nbsp;&nbsp;&nbsp;&nbsp; 如大家所说，还可以包含time.h头文件，然后使用srand(time(0))来使用当前时间使随机数发生器随机化，这样就可以保证每两次运行时可以得到不同的随机数序列(只要两次运行的间隔超过1秒)。</p>
</div>
</div><img src ="http://www.cppblog.com/softko/aggbug/135228.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/softko/" target="_blank">eircQ</a> 2010-12-02 08:42 <a href="http://www.cppblog.com/softko/archive/2010/12/02/135228.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>trie树--详解</title><link>http://www.cppblog.com/softko/archive/2010/11/26/134701.html</link><dc:creator>eircQ</dc:creator><author>eircQ</author><pubDate>Fri, 26 Nov 2010 01:48:00 GMT</pubDate><guid>http://www.cppblog.com/softko/archive/2010/11/26/134701.html</guid><wfw:comment>http://www.cppblog.com/softko/comments/134701.html</wfw:comment><comments>http://www.cppblog.com/softko/archive/2010/11/26/134701.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/softko/comments/commentRss/134701.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/softko/services/trackbacks/134701.html</trackback:ping><description><![CDATA[<p align="left"><span style="font-size: 10pt;">文章作者：</span><span style="font-size: 10pt; color: #0000ff;">yx_th000 </span><span style="font-size: 10pt;">文章来源：</span><span style="font-size: 10pt;">C</span><span style="font-size: 10pt; color: #0000ff;">herish_yimi (</span><a  href="http://www.cnblogs.com/cherish_yimi/"><span style="font-size: 10pt;">http://www.cnblogs.com/cherish_yimi/</span></a><span style="font-size: 10pt;">) 转载请注明，谢谢合作。<br></span><span style="font-size: 10pt;">关键词：trie trie树 数据结构</span></p>
<p align="left"><span style="font-size: 10pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp;前几天学习了并查集和trie树，这里总结一下trie。<br>&nbsp;&nbsp;&nbsp; 本文讨论一棵最简单的trie树，基于英文26个字母组成的字符串，讨论插入字符串、判断前缀是否存在、查找字符串等基本操作；至于trie树的删除单个节点实在是少见，故在此不做详解。</span></p>
<p style="margin: 0cm 0cm 0pt 21pt; text-indent: -21pt; text-align: left;" align="left"><span style="font-size: 10pt; font-family: Wingdings;">l<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; font-family: 宋体;">Trie</span><span style="font-size: 10pt; font-family: 宋体;">原理</span></p>
<p><span style="font-size: 10pt; font-family: 宋体;">Trie</span><span style="font-size: 10pt; font-family: 宋体;">的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;"></span></p>
<p style="margin: 0cm 0cm 0pt 21pt; text-indent: -21pt; text-align: left;" align="left"><span style="font-size: 10pt; font-family: Wingdings;">l<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; font-family: 宋体;">Trie</span><span style="font-size: 10pt; font-family: 宋体;">性质</span></p>
<p align="left"><span style="font-size: 10pt; font-family: 宋体;">好多人说trie的根节点不包含任何字符信息，我所习惯的trie根节点却是包含信息的，而且认为这样也方便，下面说一下它的性质 (基于本文所讨论的简单trie树)</span></p>
<p style="margin: 0cm 0cm 0pt 18pt; text-indent: -18pt; text-align: left;" align="left"><span style="font-size: 10pt; font-family: 宋体;">1.<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; font-family: 宋体;">字符的种数决定每个节点的出度，即branch数组(空间换时间思想)</span></p>
<p style="margin: 0cm 0cm 0pt 18pt; text-indent: -18pt; text-align: left;" align="left"><span style="font-size: 10pt; font-family: 宋体;">2.<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; font-family: 宋体;">branch</span><span style="font-size: 10pt; font-family: 宋体;">数组的下标代表字符相对于a的相对位置</span></p>
<p style="margin: 0cm 0cm 0pt 18pt; text-indent: -18pt; text-align: left;" align="left"><span style="font-size: 10pt; font-family: 宋体;">3.<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; font-family: 宋体;">采用标记的方法确定是否为字符串。</span></p>
<p style="margin: 0cm 0cm 0pt 18pt; text-indent: -18pt; text-align: left;" align="left"><span style="font-size: 10pt; font-family: 宋体;">4.<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; font-family: 宋体;">插入、查找的复杂度均为O(len),len为字符串长度<br><br></span></p>
<p style="margin: 0cm 0cm 0pt 21pt; text-indent: -21pt; text-align: left;" align="left"><span style="font-size: 10pt; font-family: Wingdings;">l<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; font-family: 宋体;">Trie</span><span style="font-size: 10pt; font-family: 宋体;">的示意图</span></p>
<p align="left"><span style="font-size: 10pt; font-family: 宋体;">如图所示，该trie树存有abc、d、da、dda四个字符串，如果是字符串会在节点的尾部进行标记。没有后续字符的branch分支指向NULL<br><br></span><span style="font-size: 10pt; font-family: Wingdings;"><span style="font: 7pt 'Times New Roman';"><span style="font-size: 10pt; font-family: Wingdings;"><span style="font-size: 10pt; font-family: 宋体;"><img  src="http://images.cnblogs.com/cnblogs_com/cherish_yimi/trieTree.JPG" alt="" width="522" border="0" height="317"><br><br><br></span><br>l<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; font-family: 宋体;">Trie</span></span></span><span style="font-size: 10pt; font-family: 宋体;">Trie</span><span style="font-size: 10pt; font-family: 宋体;">的优点举例</span></p>
<p align="left"><span style="font-size: 10pt; font-family: 宋体;">已知n个由小写字母构成的平均长度为10的单词,判断其中是否存在某个串为另一个串的前缀子串。下面对比3种方法：</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt; text-align: left;" align="left"><span style="font-size: 10pt; font-family: 宋体;">1.<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; font-family: 宋体;">最容易想到的：即从字符串集中从头往后搜，看每个字符串是否为字符串集中某个字符串的前缀，复杂度为O(n^2)。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt; text-align: left;" align="left"><span style="font-size: 10pt; font-family: 宋体;">2.<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; font-family: 宋体;">使用hash：我们用hash存下所有字符串的所有的前缀子串。建立存有子串hash的复杂度为O(n*len)。查询的复杂度为O(n)* O(1)= O(n)。</span></p>
<p style="margin: 0cm 0cm 0pt 39pt; text-indent: -18pt; text-align: left;" align="left"><span style="font-size: 10pt; font-family: 宋体;">3.<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; font-family: 宋体;">使
用trie：因为当查询如字符串abc是否为某个字符串的前缀时，显然以b,c,d....等不是以a开头的字符串就不用查找了。所以建立trie的复杂
度为O(n*len)，而建立+查询在trie中是可以同时执行的，建立的过程也就可以成为查询的过程，hash就不能实现这个功能。所以总的复杂度为
O(n*len)，实际查询的复杂度只是O(len)。<br></span></p>
<p align="left"><span style="font-size: 10pt; font-family: 宋体;"><br>解释一下
hash为什么不能将建立与查询同时执行，例如有串：911，911456输入，如果要同时执行建立与查询，过程就是查询911，没有，然后存入9、
91、911，查询911456，没有然后存入9114、91145、911456，而程序没有记忆功能，并不知道911在输入数据中出现过。所以用
hash必须先存入所有子串，然后for循环查询。</span></p>
<p align="left"><span style="font-size: 10pt; font-family: 宋体;">而trie树便可
以，存入911后，已经记录911为出现的字符串，在存入911456的过程中就能发现而输出答案；倒过来亦可以，先存入911456，在存入911时，
当指针指向最后一个1时，程序会发现这个1已经存在，说明911必定是某个字符串的前缀，该思想是我在做pku上的3630中发现的，详见本文配套的&#8220;入
门练习&#8221;。</span></p>
<p style="margin: 0cm 0cm 0pt 21pt; text-indent: -21pt; text-align: left;" align="left"><span style="font-size: 10pt; font-family: Wingdings;">l<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; font-family: 宋体;">Trie</span><span style="font-size: 10pt; font-family: 宋体;">的简单实</span><span style="font-size: 10pt; font-family: 宋体;">现(插入、查</span><span style="font-size: 10pt; font-family: 宋体;">询)<br></span></p>
<div class="cnblogs_code"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" style="display: none;" id="Code_Closed_Image_124250" width="11" align="top" height="16"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" id="Code_Open_Image_124250" style="display: inline;" width="11" align="top" height="16"><span style="display: none;" class="cnblogs_code_Collapse" id="Code_Closed_Text_124250">Code</span><span id="Code_Open_Text_124250" style="display: inline;"><br><span style="color: #008080;">&nbsp;1</span><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">iostream</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;3</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"></span><span style="color: #0000ff;">using</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">namespace</span><span style="color: #000000;">&nbsp;std;<br></span><span style="color: #008080;">&nbsp;4</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"><br></span><span style="color: #008080;">&nbsp;5</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"></span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;branchNum&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #800080;">26</span><span style="color: #000000;">;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">声明常量&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;6</span><span style="color: #008000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i;<br></span><span style="color: #008080;">&nbsp;7</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"><br></span><span style="color: #008080;">&nbsp;8</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Trie_node<br></span><span style="color: #008080;">&nbsp;9</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" id="Codehighlighter1_102_252_Open_Image" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" id="Codehighlighter1_102_252_Closed_Image" style="display: none;" align="top"></span><span id="Codehighlighter1_102_252_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif" alt=""></span><span id="Codehighlighter1_102_252_Open_Text"><span style="color: #000000;">{<br></span><span style="color: #008080;">10</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;isStr;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">记录此处是否构成一个串。</span><span style="color: #008000;"><br></span><span style="color: #008080;">11</span><span style="color: #008000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;Trie_node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">next[branchNum];</span><span style="color: #008000;">//</span><span style="color: #008000;">指向各个子树的指针,下标0-25代表26字符</span><span style="color: #008000;"><br></span><span style="color: #008080;">12</span><span style="color: #008000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;Trie_node():isStr(</span><span style="color: #0000ff;">false</span><span style="color: #000000;">)<br></span><span style="color: #008080;">13</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" id="Codehighlighter1_212_250_Open_Image" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" id="Codehighlighter1_212_250_Closed_Image" style="display: none;" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_212_250_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif" alt=""></span><span id="Codehighlighter1_212_250_Open_Text"><span style="color: #000000;">{<br></span><span style="color: #008080;">14</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(next,NULL,</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(next));<br></span><span style="color: #008080;">15</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;"><br></span><span style="color: #008080;">16</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" align="top">}</span></span><span style="color: #000000;">;<br></span><span style="color: #008080;">17</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"><br></span><span style="color: #008080;">18</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Trie<br></span><span style="color: #008080;">19</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" id="Codehighlighter1_266_407_Open_Image" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" id="Codehighlighter1_266_407_Closed_Image" style="display: none;" align="top"></span><span id="Codehighlighter1_266_407_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif" alt=""></span><span id="Codehighlighter1_266_407_Open_Text"><span style="color: #000000;">{<br></span><span style="color: #008080;">20</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">21</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;Trie();<br></span><span style="color: #008080;">22</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;insert(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;word);<br></span><span style="color: #008080;">23</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;search(</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;word);&nbsp;<br></span><span style="color: #008080;">24</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;deleteTrie(Trie_node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">root);<br></span><span style="color: #008080;">25</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top"></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br></span><span style="color: #008080;">26</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;Trie_node</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;root;<br></span><span style="color: #008080;">27</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" align="top">}</span></span><span style="color: #000000;">;<br></span><span style="color: #008080;">28</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"><br></span><span style="color: #008080;">29</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top">Trie::Trie()<br></span><span style="color: #008080;">30</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" id="Codehighlighter1_423_451_Open_Image" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" id="Codehighlighter1_423_451_Closed_Image" style="display: none;" align="top"></span><span id="Codehighlighter1_423_451_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif" alt=""></span><span id="Codehighlighter1_423_451_Open_Text"><span style="color: #000000;">{<br></span><span style="color: #008080;">31</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;root&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Trie_node();<br></span><span style="color: #008080;">32</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" align="top">}</span></span><span style="color: #000000;"><br></span><span style="color: #008080;">33</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"><br></span><span style="color: #008080;">34</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;Trie::insert(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;word)<br></span><span style="color: #008080;">35</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" id="Codehighlighter1_489_786_Open_Image" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" id="Codehighlighter1_489_786_Closed_Image" style="display: none;" align="top"></span><span id="Codehighlighter1_489_786_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif" alt=""></span><span id="Codehighlighter1_489_786_Open_Text"><span style="color: #000000;">{<br></span><span style="color: #008080;">36</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;Trie_node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">location&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;root;<br></span><span style="color: #008080;">37</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">(</span><span style="color: #000000;">*</span><span style="color: #000000;">word)<br></span><span style="color: #008080;">38</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" id="Codehighlighter1_535_746_Open_Image" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" id="Codehighlighter1_535_746_Closed_Image" style="display: none;" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_535_746_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif" alt=""></span><span id="Codehighlighter1_535_746_Open_Text"><span style="color: #000000;">{<br></span><span style="color: #008080;">39</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(location</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">next[</span><span style="color: #000000;">*</span><span style="color: #000000;">word</span><span style="color: #000000;">-</span><span style="color: #800000;">'</span><span style="color: #800000;">a</span><span style="color: #800000;">'</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;NULL)</span><span style="color: #008000;">//</span><span style="color: #008000;">不存在则建立</span><span style="color: #008000;"><br></span><span style="color: #008080;">40</span><span style="color: #008000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" id="Codehighlighter1_587_665_Open_Image" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" id="Codehighlighter1_587_665_Closed_Image" style="display: none;" align="top"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_587_665_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif" alt=""></span><span id="Codehighlighter1_587_665_Open_Text"><span style="color: #000000;">{<br></span><span style="color: #008080;">41</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Trie_node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">tmp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Trie_node();<br></span><span style="color: #008080;">42</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;location</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">next[</span><span style="color: #000000;">*</span><span style="color: #000000;">word</span><span style="color: #000000;">-</span><span style="color: #800000;">'</span><span style="color: #800000;">a</span><span style="color: #800000;">'</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;tmp;<br></span><span style="color: #008080;">43</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">44</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;location&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;location</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">next[</span><span style="color: #000000;">*</span><span style="color: #000000;">word</span><span style="color: #000000;">-</span><span style="color: #800000;">'</span><span style="color: #800000;">a</span><span style="color: #800000;">'</span><span style="color: #000000;">];&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">每插入一步，相当于有一个新串经过，指针要向下移动</span><span style="color: #008000;"><br></span><span style="color: #008080;">45</span><span style="color: #008000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;word</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br></span><span style="color: #008080;">46</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;"><br></span><span style="color: #008080;">47</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;location</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">isStr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">到达尾部,标记一个串</span><span style="color: #008000;"><br></span><span style="color: #008080;">48</span><span style="color: #008000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" align="top"></span><span style="color: #000000;">}</span></span><span style="color: #000000;"><br></span><span style="color: #008080;">49</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"><br></span><span style="color: #008080;">50</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"></span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;Trie::search(</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">word)<br></span><span style="color: #008080;">51</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" id="Codehighlighter1_818_976_Open_Image" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" id="Codehighlighter1_818_976_Closed_Image" style="display: none;" align="top"></span><span id="Codehighlighter1_818_976_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif" alt=""></span><span id="Codehighlighter1_818_976_Open_Text"><span style="color: #000000;">{<br></span><span style="color: #008080;">52</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;Trie_node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">location&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;root;<br></span><span style="color: #008080;">53</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">(</span><span style="color: #000000;">*</span><span style="color: #000000;">word&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;location)<br></span><span style="color: #008080;">54</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" id="Codehighlighter1_876_930_Open_Image" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" id="Codehighlighter1_876_930_Closed_Image" style="display: none;" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_876_930_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif" alt=""></span><span id="Codehighlighter1_876_930_Open_Text"><span style="color: #000000;">{<br></span><span style="color: #008080;">55</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;location&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;location</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">next[</span><span style="color: #000000;">*</span><span style="color: #000000;">word</span><span style="color: #000000;">-</span><span style="color: #800000;">'</span><span style="color: #800000;">a</span><span style="color: #800000;">'</span><span style="color: #000000;">];<br></span><span style="color: #008080;">56</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;word</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br></span><span style="color: #008080;">57</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;"><br></span><span style="color: #008080;">58</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">(location</span><span style="color: #000000;">!=</span><span style="color: #000000;">NULL&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;location</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">isStr);<br></span><span style="color: #008080;">59</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" align="top">}</span></span><span style="color: #000000;"><br></span><span style="color: #008080;">60</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"><br></span><span style="color: #008080;">61</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;Trie::deleteTrie(Trie_node&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">root)<br></span><span style="color: #008080;">62</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" id="Codehighlighter1_1017_1138_Open_Image" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" id="Codehighlighter1_1017_1138_Closed_Image" style="display: none;" align="top"></span><span id="Codehighlighter1_1017_1138_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif" alt=""></span><span id="Codehighlighter1_1017_1138_Open_Text"><span style="color: #000000;">{<br></span><span style="color: #008080;">63</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #800080;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;branchNum;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br></span><span style="color: #008080;">64</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" id="Codehighlighter1_1052_1122_Open_Image" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" id="Codehighlighter1_1052_1122_Closed_Image" style="display: none;" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_1052_1122_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif" alt=""></span><span id="Codehighlighter1_1052_1122_Open_Text"><span style="color: #000000;">{<br></span><span style="color: #008080;">65</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(root</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">next[i]&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;NULL)<br></span><span style="color: #008080;">66</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" id="Codehighlighter1_1084_1119_Open_Image" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" id="Codehighlighter1_1084_1119_Closed_Image" style="display: none;" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_1084_1119_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif" alt=""></span><span id="Codehighlighter1_1084_1119_Open_Text"><span style="color: #000000;">{<br></span><span style="color: #008080;">67</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;deleteTrie(root</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">next[i]);<br></span><span style="color: #008080;">68</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;"><br></span><span style="color: #008080;">69</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;"><br></span><span style="color: #008080;">70</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;root;<br></span><span style="color: #008080;">71</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" align="top">}</span></span><span style="color: #000000;"><br></span><span style="color: #008080;">72</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"><br></span><span style="color: #008080;">73</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top"></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;main()&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">简单测试</span><span style="color: #008000;"><br></span><span style="color: #008080;">74</span><span style="color: #008000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" id="Codehighlighter1_1159_1325_Open_Image" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" id="Codehighlighter1_1159_1325_Closed_Image" style="display: none;" align="top"></span><span id="Codehighlighter1_1159_1325_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif" alt=""></span><span id="Codehighlighter1_1159_1325_Open_Text"><span style="color: #000000;">{<br></span><span style="color: #008080;">75</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;Trie&nbsp;t;<br></span><span style="color: #008080;">76</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;t.insert(</span><span style="color: #800000;">"</span><span style="color: #800000;">a</span><span style="color: #800000;">"</span><span style="color: #000000;">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">77</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;t.insert(</span><span style="color: #800000;">"</span><span style="color: #800000;">abandon</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br></span><span style="color: #008080;">78</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;c&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #800000;">"</span><span style="color: #800000;">abandoned</span><span style="color: #800000;">"</span><span style="color: #000000;">;<br></span><span style="color: #008080;">79</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;t.insert(c);<br></span><span style="color: #008080;">80</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;t.insert(</span><span style="color: #800000;">"</span><span style="color: #800000;">abashed</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br></span><span style="color: #008080;">81</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(t.search(</span><span style="color: #800000;">"</span><span style="color: #800000;">abashed</span><span style="color: #800000;">"</span><span style="color: #000000;">))<br></span><span style="color: #008080;">82</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #800000;">"</span><span style="color: #800000;">true\n</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br></span><span style="color: #008080;">83</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" align="top">}</span></span></span></div>
<br><img src ="http://www.cppblog.com/softko/aggbug/134701.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/softko/" target="_blank">eircQ</a> 2010-11-26 09:48 <a href="http://www.cppblog.com/softko/archive/2010/11/26/134701.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>常用函数的源码实现</title><link>http://www.cppblog.com/softko/archive/2010/08/23/124416.html</link><dc:creator>eircQ</dc:creator><author>eircQ</author><pubDate>Mon, 23 Aug 2010 06:42:00 GMT</pubDate><guid>http://www.cppblog.com/softko/archive/2010/08/23/124416.html</guid><wfw:comment>http://www.cppblog.com/softko/comments/124416.html</wfw:comment><comments>http://www.cppblog.com/softko/archive/2010/08/23/124416.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/softko/comments/commentRss/124416.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/softko/services/trackbacks/124416.html</trackback:ping><description><![CDATA[<p>;***************************************************************************************************************
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strlen returns the length of a null-terminated string in
bytes, not including the null byte itself.
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Algorithm:
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int strlen (const char * str)
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int length = 0;
<br>;
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while( *str++ )
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++length;
<br>;
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return( length );
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>
<br>;***************************************************************************************************************
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy() copies a source memory buffer to a destination
buffer.
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Overlapping buffers are not treated specially, so
propogation may occur.
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Algorithm:
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void * memcpy(void * dst, void * src, size_t count)
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void * ret = dst;
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * copy from lower addresses to higher addresses
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (count--)
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *dst++ = *src++;
<br>;
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(ret);
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>
<br>;***************************************************************************************************************
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memmove() copies a source memory buffer to a destination
memory buffer.
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This routine recognize overlapping buffers to avoid
propogation.
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For cases where propogation is not a problem, memcpy() can
be used.
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Algorithm:
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void * memmove(void * dst, void * src, size_t count)
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void * ret = dst;
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dst &lt;= src || dst &gt;= (src + count)) {
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Non-Overlapping Buffers
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * copy from lower addresses to higher
addresses
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (count--)
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *dst++ = *src++;
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Overlapping Buffers
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * copy from higher addresses to lower
addresses
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dst += count - 1;
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; src += count - 1;
<br>;
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (count--)
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *dst-- = *src--;
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>;
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(ret);
<br>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>
<br>;***************************************************************************************************************
<br>int&nbsp;strcmp(const&nbsp;char&nbsp;*str1,const&nbsp;char&nbsp;*str2)
<br>{
<br>while((*str1==*str2)&amp;&amp;(*str1))
<br>{
<br>str1++;
<br>str2++;
<br>}
<br>if((*str1==*str2)&amp;&amp;(!*str1)) //Same&nbsp;strings
<br>return&nbsp;0;
<br>else&nbsp;if((*str1)&amp;&amp;(!*str2))&nbsp; //Same&nbsp;but&nbsp;str1&nbsp;longer
<br>return&nbsp;-1;
<br>else&nbsp;if((*str2)&amp;&amp;(!*str1)) //Same&nbsp;but&nbsp;str2&nbsp;longer
<br>return 1;
<br>else
<br>return((*str1&gt;*str2)?-1:1);
<br>}
<br>
<br>;***************************************************************************************************************
<br>char *strstr1(const char *str1, const char *str2)
<br>{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char *cp = (char *)str1;&nbsp; //type transfer
<br>&nbsp;&nbsp;&nbsp;&nbsp; char *s1, *s2;
<br>&nbsp;&nbsp;&nbsp;&nbsp; if(!str2)&nbsp;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (char *)str1;
<br>&nbsp;&nbsp;&nbsp;&nbsp; while (cp)
<br>&nbsp;&nbsp;&nbsp;&nbsp; {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s1 = cp;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s2 = (char *)str2;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while( !s1 &amp;&amp; !s2 &amp;&amp; !(*s1-*s2))
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s1++, s2++;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!s2)&nbsp;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return cp;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cp++;
<br>&nbsp;&nbsp;&nbsp;&nbsp; }
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return NULL;
<br>}
<br>
<br>;***************************************************************************************************************
<br>*char *_itoa, *_ltoa, *_ultoa(val, buf, radix) - convert binary int
to ASCII string
<br>static void __cdecl xtoa (unsigned long val, char *buf, unsigned
radix, int is_neg )
<br>{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char *p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* pointer to traverse string */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char *firstdig;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* pointer to first digit */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char temp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* temp char */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned digval;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* value of digit */
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p = buf;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (is_neg) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* negative, so output '-' and negate */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *p++ = '-';
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val = (unsigned long)(-(long)val);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; firstdig = p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* save pointer to first digit */</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; digval = (unsigned) (val % radix);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val /= radix;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* get next digit */
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* convert to ascii and store */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (digval &gt; 9)
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *p++ = (char) (digval - 10 + 'a');&nbsp; /* a letter */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *p++ = (char) (digval + '0');&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* a digit */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } while (val &gt; 0);
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* We now have the digit of the number in the buffer, but in
reverse
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; order.&nbsp; Thus we reverse them now. */
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *p-- = '\0';&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* terminate string; p points to last
digit */</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp = *p;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *p = *firstdig;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *firstdig = temp;&nbsp;&nbsp; /* swap *p and *firstdig */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --p;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++firstdig;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* advance to next two digits */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } while (firstdig &lt; p); /* repeat until halfway */
<br>}
<br>char * __cdecl _itoa ( int val, char *buf, int radix )
<br>{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (radix == 10 &amp;&amp; val &lt; 0)
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xtoa((unsigned long)val, buf, radix, 1);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xtoa((unsigned long)(unsigned int)val, buf, radix, 0);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return buf;
<br>}
<br>char * __cdecl _ltoa ( long val, char *buf, int radix )
<br>{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xtoa((unsigned long)val, buf, radix, (radix == 10 &amp;&amp;
val &lt; 0));
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return buf;
<br>}
<br>
<br>;***************************************************************************************************************
<br>*long atol(char *nptr) - Convert string to long.&nbsp;Overflow is not
detected.
<br>long __cdecl _tstol(const _TCHAR *nptr )
<br>{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int c;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* current char */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long total;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* current total */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sign;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* if '-', then negative, otherwise
positive */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ( _istspace((int)(_TUCHAR)*nptr) )
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++nptr;&nbsp; &nbsp;/* skip whitespace */
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = (int)(_TUCHAR)*nptr++;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sign = c;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* save sign indication */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (c == _T('-') || c == _T('+'))
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = (int)(_TUCHAR)*nptr++;&nbsp;&nbsp;&nbsp; /* skip sign */
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; total = 0;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ( (c = _tchartodigit(c)) != -1 ) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; total = 10 * total + c;&nbsp;&nbsp;&nbsp;&nbsp; /* accumulate digit */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = (_TUCHAR)*nptr++;&nbsp;&nbsp;&nbsp; /* get next char */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (sign == '-')
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -total;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return total;&nbsp;&nbsp; /* return result, negated if necessary
*/
<br>}
<br>int __cdecl _tstoi( const _TCHAR *nptr )
<br>{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (int)_tstol(nptr);
<br>}
<br>
<br>;***************************************************************************************************************
<br>;performs a byteswap on an unsigned integer.
<br>unsigned short __cdecl _byteswap_ushort(unsigned short i)
<br>{
<br>&nbsp;&nbsp;&nbsp; unsigned short j;
<br>&nbsp;&nbsp;&nbsp; j =&nbsp; (i &lt;&lt; 8) ;
<br>&nbsp;&nbsp;&nbsp; j += (i &gt;&gt; 8) ;
<br>&nbsp;&nbsp;&nbsp; return j;
<br>}
<br>unsigned long __cdecl _byteswap_ulong(unsigned long i)
<br>{
<br>&nbsp;&nbsp;&nbsp; unsigned int j;
<br>&nbsp;&nbsp;&nbsp; j =&nbsp; (i &lt;&lt; 24);
<br>&nbsp;&nbsp;&nbsp; j += (i &lt;&lt;&nbsp; 8) &amp; 0x00FF0000;
<br>&nbsp;&nbsp;&nbsp; j += (i &gt;&gt;&nbsp; 8) &amp; 0x0000FF00;
<br>&nbsp;&nbsp;&nbsp; j += (i &gt;&gt; 24);
<br>&nbsp;&nbsp;&nbsp; return j;
<br>}
<br>
<br>;***************************************************************************************************************
<br>*char *bsearch() - do a binary search on an array
<br>*Entry:
<br>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const char *key&nbsp;&nbsp;&nbsp; - key to search for const char *base&nbsp;&nbsp; -
base of sorted array to search unsigned int num&nbsp;&nbsp; - number of *elements
in array unsigned int width - number of bytes per element int
(*compare)()&nbsp;&nbsp; - pointer to function that compares two
<br>*array elements, returning neg when #1 &lt; #2, pos when #1 &gt; #2,
and 0 when they are equal. Function is passed pointers to two
<br>*array elements.
<br>*Exit:
<br>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if key is found: returns pointer to occurrence of key in
array
<br>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if key is not found:returns NULL
<br>
<br>void * __cdecl bsearch ( REG4 const void *key, const void *base,
size_t num, size_t width, int (__cdecl *compare)(const void *, const
void *)&nbsp;&nbsp; )
<br>{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; REG1 char *lo = (char *)base;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; REG2 char *hi = (char *)base + (num - 1) * width;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; REG3 char *mid;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size_t half;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int result;
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (lo &lt;= hi)
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (half = num / 2)
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mid = lo + (num &amp; 1 ? half : (half - 1))
* width;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!(result = (*compare)(key,mid)))
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(mid);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (result &lt; 0)
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hi = mid - width;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; num = num &amp; 1 ? half : half-1;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lo = mid + width;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; num = half;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (num)
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return((*compare)(key,lo) ? NULL : lo);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(NULL);
<br>}
<br>
<br>;***************************************************************************************************************
<br>void __cdecl _tmakepath (register _TSCHAR *path, const _TSCHAR
*drive, const _TSCHAR *dir,
<br>const _TSCHAR *fname, const _TSCHAR *ext&nbsp; )
<br>{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;register const _TSCHAR *p;
<br>&nbsp;&nbsp;&nbsp;&nbsp; /* copy drive */
<br>&nbsp;&nbsp;&nbsp;&nbsp; if (drive &amp;&amp; *drive) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *path++ = *drive;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *path++ = _T(':');
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* copy dir */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((p = dir) &amp;&amp; *p) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *path++ = *p++;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }while (*p);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (*(p-1) != _T('/') &amp;&amp; *(p-1) != _T('\\'))
{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *path++ = _T('\\');
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* copy fname */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (p = fname) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (*p) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *path++ = *p++;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* copy ext, including 0-terminator - check to see if a '.'
needs to be inserted. */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (p = ext) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (*p &amp;&amp; *p != _T('.')) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *path++ = _T('.');
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (*path++ = *p++)
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* better add the 0-terminator */
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *path = _T('\0');
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>}
</p>
<br><img src ="http://www.cppblog.com/softko/aggbug/124416.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/softko/" target="_blank">eircQ</a> 2010-08-23 14:42 <a href="http://www.cppblog.com/softko/archive/2010/08/23/124416.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>两单向链表相交</title><link>http://www.cppblog.com/softko/archive/2010/08/18/123811.html</link><dc:creator>eircQ</dc:creator><author>eircQ</author><pubDate>Wed, 18 Aug 2010 03:26:00 GMT</pubDate><guid>http://www.cppblog.com/softko/archive/2010/08/18/123811.html</guid><wfw:comment>http://www.cppblog.com/softko/comments/123811.html</wfw:comment><comments>http://www.cppblog.com/softko/archive/2010/08/18/123811.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/softko/comments/commentRss/123811.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/softko/services/trackbacks/123811.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; 1. /***********************************/ &nbsp;<br>&nbsp;&nbsp; 2. /* 功能：求两个单链表是否相交和交点*/ &nbsp;<br>&nbsp;&nbsp; 3. /* 转载自CSDN博客&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * / &nbsp;<br>&nbsp;&nbsp; 4. /* 日期：2010/03/29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */ &nbsp;<br>&nbsp;&nbsp; 5. /***********************************/ &nbsp;<br>&nbsp;&nbsp; 6.&nbsp; &nbsp;<br>&nbsp;&nbsp; 7.&nbsp; &nbsp;<br>&nbsp;&nbsp; 8. Node* find(Node* head1,Node* head2)&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; 9. {&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp; 10.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Node *p1=head1,*p2=head2;&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp; 11.&nbsp;&nbsp;&nbsp;&nbsp; int m=0,n=0;&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp; 12.&nbsp;&nbsp;&nbsp;&nbsp; while(p1)//O(len1)&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp; 13.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp; 14.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p1=p1-&gt;next;&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp; 15.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m++;<br>&nbsp; 16.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp; 17.&nbsp;&nbsp;&nbsp;&nbsp; while(p2)//O(len2)<br>&nbsp; 18.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp; 19.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p2=p2-&gt;next;&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp; 20.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n++;&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp; 21.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp; 22.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p1=head1;<br>&nbsp; 23.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p2=head2;<br>&nbsp; 24.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp; 25.&nbsp;&nbsp;&nbsp;&nbsp; if(m&gt;n)<br>&nbsp; 26.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp; 27.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0;i&lt;m-n;i++)&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp; 28.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p1=p1-&gt;next;&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp; 29.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp; 30.&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp; 31.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp; 32.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0;i&lt;n-m;i++) <br>&nbsp; 33.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; p2=p2-&gt;next;<br>&nbsp; 34.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//O(abs(len1-len2))<br>&nbsp; 35.&nbsp;&nbsp;&nbsp;&nbsp; while(p1!=p2)<br>&nbsp; 36.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp; 37.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p1=p1-&gt;next;<br>&nbsp; 38.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p2=p2-&gt;next;&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp; 39.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//O(min(len1,len2))&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp; 40.&nbsp;&nbsp;&nbsp;&nbsp; return p1;<br>&nbsp; 41. }
<br><img src ="http://www.cppblog.com/softko/aggbug/123811.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/softko/" target="_blank">eircQ</a> 2010-08-18 11:26 <a href="http://www.cppblog.com/softko/archive/2010/08/18/123811.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c与汇编，以及嵌入式工程师应注意的问题</title><link>http://www.cppblog.com/softko/archive/2010/07/25/121229.html</link><dc:creator>eircQ</dc:creator><author>eircQ</author><pubDate>Sun, 25 Jul 2010 03:43:00 GMT</pubDate><guid>http://www.cppblog.com/softko/archive/2010/07/25/121229.html</guid><wfw:comment>http://www.cppblog.com/softko/comments/121229.html</wfw:comment><comments>http://www.cppblog.com/softko/archive/2010/07/25/121229.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/softko/comments/commentRss/121229.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/softko/services/trackbacks/121229.html</trackback:ping><description><![CDATA[<h3 class="title pre fs1"><span class="tcnt">c与汇编，以及嵌入式工程师应注意的问题</span><span class="bgc0 fc07 fw0 fs0"></span></h3>
<p class="tdep clearfix nbw-act fc06">
<span class="pleft">
<a  href="http://meizhe143.blog.163.com/blog/#m=0&amp;t=1&amp;c=fks_080066084080086066085074085075093085089064082" class="fc03 m2a">人生哲理与经验</a>
<span class="sep">2007-07-25 13:31:04</span>
<span class="sep">阅读<span id="$_spanReadCount">41</span></span>
<span class="sep">评论<span id="$_spanCommentCount">1</span></span>
</span>
<span class="pright fc07 ztag">字号：<span class="ul sep fc04">大</span><span class="ul sep fc04">中</span><span class="sep ul fc04 selected js-fcurrent fc05">小</span></span>
</p>
<div class="bct fc05 fc11 nbw-blog ztag js-fs2">　汇编和c同样重要，相互配合，缺一不可！
<p>　　汇编的重要性：</p>
<p>◆ 帮助你从根本上彻底和完全了解芯片的结构和性能，以及工作原理，如何使用。 <br>◆ 在小的芯片上实现小的系统。 <br>◆ 系统的调试。尽管你使用了高级语言，在调试中可以帮助你了解C代码的性能和特点，甚至找到使用开发平台本身的BUG。 <br>◆ 编写时序要求严格的代码，实现一些高级语言不易实现的功能。 </p>
<p>　　将出版的AVR128的书里面，第五章中主使用C作为系统开发设计语言，这是因为M128的速度高，内部有4K的RAM，128KFLASH，
适合于实现比较高级的应用，所以采用C语言作为系统开发的设计语言。但作为开发工程师来讲，熟悉M128的结构和应用原理，基本掌握它的汇编语言是必要的
基础。 </p>
<p>　　从目前的技术和应用发展来看，对硬件工程师的要求越来越高。以我的观点，作为单片机和嵌入式系统开发真正的高手，应具备以下几个方面的综合能力： </p>
<p>◆ 硬件。模拟、数字电路的雄厚基础，了解跟踪现在市场上的各种元器件的应用和发展，能够进行可靠、完善的电路设计以及PCB的设计。 <br>◆
软件。不仅需要精通汇编语言，也要精通C语言，要有好的单片机系统程序设计理念和能力，学校中学的那些分支结构、循环结构等基本原理远远不够！要有基本的
数据结构的知识。否则你如何设计实现USB HOST读U盘的接口？如何实现嵌入式WEB系统？以及如何使用真正了解和使用RTOS？ <br>◆ 具备计算机网络和数字通信的基础知识，从根本上熟悉和了解各种协议的构造和实现，如：UART、RS232、SPI、I2C、USB、IEEE802、TCP/IP等。 <br>◆ 计算机应用的高手。 <br>◆ 熟练阅读英文资料。 <br>◆ 热爱和喜欢电子技术，具备刻苦精神、踏踏实实，不弄虚作假，不浮躁。多动手，勤实践。有强烈的专业和钻研精神。最后一条最重要！ </p>
</div><img src ="http://www.cppblog.com/softko/aggbug/121229.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/softko/" target="_blank">eircQ</a> 2010-07-25 11:43 <a href="http://www.cppblog.com/softko/archive/2010/07/25/121229.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>