<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>C&#43;&#43; on bystander&#39;s blog</title>
    <link>http://blog.leaver.me/tags/c&#43;&#43;/</link>
    <description>Recent content in C&#43;&#43; on bystander&#39;s blog</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Sun, 02 Jun 2013 15:44:22 +0000</lastBuildDate>
    <atom:link href="http://blog.leaver.me/tags/c++/rss.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>阿里巴巴5月5日综合算法题详解</title>
      <link>http://blog.leaver.me/2013/06/02/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B45%E6%9C%885%E6%97%A5%E7%BB%BC%E5%90%88%E7%AE%97%E6%B3%95%E9%A2%98%E8%AF%A6%E8%A7%A3/</link>
      <pubDate>Sun, 02 Jun 2013 15:44:22 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/06/02/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B45%E6%9C%885%E6%97%A5%E7%BB%BC%E5%90%88%E7%AE%97%E6%B3%95%E9%A2%98%E8%AF%A6%E8%A7%A3/</guid>
      <description>&lt;p&gt;之前参加了阿里的笔试和电面，让后天那个敏感的日子去参加现场面，就去看了一下那天笔试的最后一道综合题，看着网上清一色最后一道题不知道从哪转的答案，不忍直视，一看代码就是错的，最直接的就是求中位数连奇偶性都不判断，直接处以2..这，另外当在无法整除的情况下，数据结果错误。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;这道题的大意是：有一个淘宝商户，在某城市有n个仓库，每个仓库的储货量不同，现在要通过货物运输，将每次仓库的储货量变成一致的，n个仓库之间的运输线路围城一个圈，即1-&amp;gt;2-&amp;gt;3-&amp;gt;4-&amp;gt;&amp;hellip;-&amp;gt;n-&amp;gt;1-&amp;gt;&amp;hellip;，货物只能通过连接的仓库运输，设计最小的运送成本（运货量*路程）达到淘宝商户的要求，并写出代码。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解题思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;假设n个仓库的初始储货量分别为warehouse[1],warehouse[2],&amp;hellip;,warehouse[n]
计算平均储货量&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt; average = （warehouse[1]+warehouse[2]+...+warehouse[n])/n&lt;/pre&gt;
&lt;p&gt;就算出来了最终的结果中，每个仓库应该有的存量
首先，从仓库1向仓库n运送k；
然后，从1到n-1，依次向下运送某一特定值，使得每一个仓库的余量都为average，剩下的问题就是求总代价的最小值了。&lt;/p&gt;
&lt;p&gt;设第0步从1仓库向n仓库（注意因为是圆圈，所以路径长度是1）运出k存量，k可以为负，如果为负数，意味着从n向1运输|k|存量，然后从循环，从（1到n-1）,从i仓库向i+1仓库运输，运输的量需要保证i仓库在运输完毕后等于average&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;第0步（从仓库1向仓库n运送k）:花费代价为 |k|，&lt;/li&gt;
&lt;li&gt;第1步（确保仓库1的余量为average）：需要花费代价为&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;|warehouse[1]-average-k|&lt;/pre&gt;
&lt;p&gt;也就是从1向2伙从2向1运输
3.  第2步（确保仓库2的余量为average）：代价为&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;|warehouse[2]+warehouse[1]-average-k-average|=|warehouse[1]+warehouse[2]-2*average-k|&lt;/pre&gt;
&lt;p&gt;&amp;hellip;
n-1.第n-1步：代价为&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;|warehouse[1]+warehouse[2]+...+warehouse[n-1]-(n-1)*average-k|&lt;/pre&gt;
&lt;p&gt;此时，仓库n剩下的货物量：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;(warehouse[n]+k)+warehouse[1]+warehouse[2]+...+warehouse[n-1]-(n-1)*average-k=(warehouse[1]+warehouse[2]+...+warehouse[n])-(n-1)*average=average&lt;/pre&gt;
&lt;p&gt;刚好也满足，其实这里不用推导，因为平均值是算好的，所以最胡一定是刚好完成的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;总的代价为&lt;/strong&gt;：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;|k|+|warehouse[1]-average-k|+|warehouse[1]+a[2]-2*average-k|+...+|warehouse[1]+warehouse[2]+...+warehouse[n-1]-(n-1)*average-k|&lt;/pre&gt;
&lt;p&gt;不妨令sum[i] = warehouse[1]+warehouse[2]+&amp;hellip;+warehouse[i]-i*average
则，总代价可表示为：|k|+|sum[1]-k|+|sum[2]-k|+&amp;hellip;+|sum[n-1]-k|
这个式子可以看成在水平数轴上寻找一个点k，使得点k到点0,sum[1],sum[2],sum[3],&amp;hellip;,sum[n-1]的距离之和最小，显然k应该取这n个数的中位数。至此问题解决。&lt;/p&gt;
&lt;p&gt;给出详细注释代码：&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &#34;stdafx.h&#34;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include&amp;lt;string&amp;gt;

using namespace std;

const int X = 100000;
double sum[X],warehouse[X];
int n;

double Abs(double x)
{
	return max(x,-x);
}

int _tmain(int argc, _TCHAR* argv[])
{
	while(true)
	{
		double total = 0;
		double mid=0;
		cout&amp;lt;&amp;lt;&#34;请输入仓库数目：&#34;;
		cin&amp;gt;&amp;gt;n;
		//读入n个仓库的值，并计算总数
		for(int i=1;i&amp;lt;=n;i++)
		{
			cout&amp;lt;&amp;lt;&#34;请输入第&#34;&amp;lt;&amp;lt;i&amp;lt;&amp;lt;&#34;个仓库的存量：&#34;;
			cin&amp;gt;&amp;gt;warehouse[i];
			total += warehouse[i];
		}
		//计算每个仓库应该最终存储的值
		double average = total/n;
		//计算sum数组
		for(int i=1;i&amp;lt;n;i++)
			sum[i] = warehouse[i]+sum[i-1]-average;
		//排序后打算去中位数
		//sort采用半开半闭区间，所以排序为0～n-1
		sort(sum,sum+n);
		//这个可以自己举个数字就知道了
		if(n%2!=0)
		{	
			mid = sum[n/2];
		}
		else
		{
			mid=(sum[n/2]+sum[n/2-1])/2;
		}
		cout&amp;lt;&amp;lt;&#34;应该从1开始,运输&#34;&amp;lt;&amp;lt;mid&amp;lt;&amp;lt;&#34;货物,然后依次保证符合条件即可&#34;&amp;lt;&amp;lt;endl;
		double ans = Abs(mid);
		for(int i=1;i&amp;lt;n;i++)
			ans += Abs(sum[i]-mid);
		cout&amp;lt;&amp;lt;&#34;总成本花费是:&#34;&amp;lt;&amp;lt;ans&amp;lt;&amp;lt;endl;
		cout&amp;lt;&amp;lt;&#34;----------------------------------------------------------------------&#34;&amp;lt;&amp;lt;endl;
	}
	return 0;
}&lt;/pre&gt;
&lt;p&gt;思路借鉴了：&lt;a href=&#34;http://hi.baidu.com/hujunjiehit/item/54204f01931ee6c49157184c&#34;&gt;http://hi.baidu.com/hujunjiehit/item/54204f01931ee6c49157184c&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;错误之处欢迎留言指出..&lt;/p&gt;</description>
    </item>
    <item>
      <title>邻接表实现无向图(C&#43;&#43;)</title>
      <link>http://blog.leaver.me/2013/05/31/%E9%82%BB%E6%8E%A5%E8%A1%A8%E5%AE%9E%E7%8E%B0%E6%97%A0%E5%90%91%E5%9B%BEc/</link>
      <pubDate>Fri, 31 May 2013 15:05:29 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/05/31/%E9%82%BB%E6%8E%A5%E8%A1%A8%E5%AE%9E%E7%8E%B0%E6%97%A0%E5%90%91%E5%9B%BEc/</guid>
      <description>&lt;p&gt;很早以前写的代码了，贴出来做个备份吧。用向量来存储一条邻接链表，存储可连通值。实现了判断是否连通，添加边，添加顶点的功能。&lt;/p&gt;
&lt;p&gt;UnDirectGraph.h&lt;/p&gt;
&lt;pre class=&#34;show-lang:1 lang:default decode:true&#34;&gt;#pragma once

#include &#34;stdafx.h&#34;
#include &amp;lt;vector&amp;gt;
using namespace std;
class UnDirectGraph
{
private:
	int vCount;
	vector&amp;lt;int&amp;gt; *adj;
public:
	int GetVCount();
	UnDirectGraph(int vCount);
	void AddEdge(int v,int w);
	vector&amp;lt;int&amp;gt; &amp;amp;Vadj(int v);
	bool IsConnected(int v,int w);
};&lt;/pre&gt;
&lt;p&gt;UnDirectGraph.cpp&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#pragma once

#include &#34;stdafx.h&#34;
#include &#34;UnDirectGraph.h&#34;
using namespace std;
UnDirectGraph::UnDirectGraph(int _vCount)
{
	this-&amp;gt;vCount=_vCount;
	adj=new vector&amp;lt;int&amp;gt;[vCount];

	for (int i=0;i&amp;lt;vCount;i++)
	{
			adj[i].clear();
	}

}
void UnDirectGraph::AddEdge(int v,int w)
{
	adj[v].push_back(w);
	adj[w].push_back(v);
}

vector&amp;lt;int&amp;gt;&amp;amp; UnDirectGraph::Vadj(int v)
{
	return adj[v];
}

bool UnDirectGraph::IsConnected(int v,int w)
{
	for (vector&amp;lt;int&amp;gt;::iterator iter=adj[v].begin();iter!=adj[v].end();iter++)
	{
		if (*iter==w)
		{
			return true;
		}
	}
	return false;
}

int UnDirectGraph::GetVCount()
{
	return vCount;
}&lt;/pre&gt;
&lt;p&gt;代码还算清晰，就不解释了，有问题留言反馈。谢谢。&lt;/p&gt;</description>
    </item>
    <item>
      <title>求整数1-N范围和为N的所有组合</title>
      <link>http://blog.leaver.me/2013/05/27/%E6%B1%82%E6%95%B4%E6%95%B01-n%E8%8C%83%E5%9B%B4%E5%92%8C%E4%B8%BAn%E7%9A%84%E6%89%80%E6%9C%89%E7%BB%84%E5%90%88/</link>
      <pubDate>Mon, 27 May 2013 10:55:49 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/05/27/%E6%B1%82%E6%95%B4%E6%95%B01-n%E8%8C%83%E5%9B%B4%E5%92%8C%E4%B8%BAn%E7%9A%84%E6%89%80%E6%9C%89%E7%BB%84%E5%90%88/</guid>
      <description>&lt;p&gt;看到的一道题，给出答案&lt;/p&gt;
&lt;p&gt;问题：找出整数1~N范围和为N的所有集合，集合里的数不允许重复。&lt;/p&gt;
&lt;p&gt;解答：递归吧&lt;/p&gt;
&lt;p&gt;代码如下：&lt;/p&gt;
&lt;pre class=&#34;lang:c++ decode:true&#34;&gt;#include &#34;stdafx.h&#34;
#include &amp;lt;iostream&amp;gt;
using namespace std;

void PrintResult(int *log,int index)
{
	for (int i = 0; i &amp;lt;index; ++i)
	{
		cout&amp;lt;&amp;lt;log[i]&amp;lt;&amp;lt;&#34; &#34;;
	}
	cout&amp;lt;&amp;lt;endl;
}

void CalCombination(int* log,int startNum,int N,int &amp;amp;index)
{
	if (N==0)
	{
		PrintResult(log,index);
	}

	else
	{
		for (int i = startNum; i &amp;lt;= N; ++i)
		{
			log[index++]=i;
			CalCombination(log,i+1,N-i,index);
		}
	}
	index--;
}

int _tmain(int argc, _TCHAR* argv[])
{
	cout&amp;lt;&amp;lt;&#34;请输入N:&#34;;
	int N=20;
	cin&amp;gt;&amp;gt;N;
	int *log=new int[N];
	int index=0;
	CalCombination(log,1,N,index);
}&lt;/pre&gt;
&lt;p&gt;要是允许重复，也简单，将递归中的这句话改为：&lt;/p&gt;
&lt;pre&gt;CalCombination(log,i,N-i,index);&lt;/pre&gt;
&lt;p&gt;同理，还可以解决类似给定一个数组，让求和为N的元素组合，只需要现将元素排个序，然后思路相同。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>引用和指针(C&#43;&#43;)</title>
      <link>http://blog.leaver.me/2013/05/22/%E5%BC%95%E7%94%A8%E5%92%8C%E6%8C%87%E9%92%88c/</link>
      <pubDate>Wed, 22 May 2013 16:16:24 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/05/22/%E5%BC%95%E7%94%A8%E5%92%8C%E6%8C%87%E9%92%88c/</guid>
      <description>&lt;p&gt;今天在整理收藏夹的时候，又看到了这两篇非常不错的文章，关于指针和引用的，我就不翻译了，文章很简单，不过把其中我觉得很有意思的两部分结合我的理解希望说的更清楚,假定你读这篇文章之前已经知道指针，但是不是很清楚其中的部分。&lt;/p&gt;
&lt;p&gt;首先是关于指针的一个直观的一个认识.&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &amp;lt;iostream&amp;gt;

int main()
{
  using namespace std;

// 声明并初始化指针.
  unsigned short int * pPointer = 0;
// 定义一个unsigned short int 变量 值为35698
  unsigned short int twoInt = 35698;
// 定义一个unsigned short int 变量 值为 77
  unsigned short int oneInt = 77;
// 使用&amp;amp;操作符将twoInt的地址赋给指针
  pPointer = &amp;amp;twoInt;
// pPointer 现在的值就是twoInt的地址了

// 打印
  cout &amp;lt;&amp;lt; &#34;pPointer的内存地址:\t\t&#34; &amp;lt;&amp;lt; &amp;amp;pPointer &amp;lt;&amp;lt; endl;
  cout &amp;lt;&amp;lt; &#34;oneInt的内存地址:\t&#34; &amp;lt;&amp;lt; &amp;amp;oneInt &amp;lt;&amp;lt; &#34;\t整数值:\t&#34; &amp;lt;&amp;lt; oneInt &amp;lt;&amp;lt; endl;
  cout &amp;lt;&amp;lt; &#34;twoInt的内存地址:\t&#34; &amp;lt;&amp;lt; &amp;amp;twoInt &amp;lt;&amp;lt; &#34;\t整数值:\t&#34; &amp;lt;&amp;lt; twoInt &amp;lt;&amp;lt; endl;
  cout &amp;lt;&amp;lt; &#34;pPointer所指向的地址(也就是pPoint的值):\t&#34; &amp;lt;&amp;lt; pPointer &amp;lt;&amp;lt; &#34;\t整数值:\t&#34; &amp;lt;&amp;lt; *pPointer &amp;lt;&amp;lt; endl;

return 0;
}&lt;/pre&gt;
&lt;p&gt;上面这段代码，声明了一个指针，和两个整数，指针指向第一个整数，然后输出结果（每个人的输出结果不一样）是：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;pPointer的内存地址:                   0xbff43314
oneInt的内存地址:                     0xbff43318       整数值:  77
twoInt的内存地址:                     0xbff4331a       整数值:  35698
pPointer所指向的地址(也就是pPoint的值): 0xbff4331a       整数值:  35698&lt;/pre&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/36294_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ef97273d51f6843eb062463a3091a8edb177b30e.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这张图是这几个变量的内存分布图，上面一排是内存地址编号，正对我们的是该处的值&lt;/p&gt;
&lt;p&gt;指针pPointer这个变量从最左边0xbff43314这个内存位置开始，占用了四个字节，这个一个指针占四个字节，大家都知道的，这个变量的值是一个地址，也就是他的指向地址。&lt;/p&gt;
&lt;p&gt;pPointer 所指向的地址呢，是一个short int 类型的值所在的位置，在这里就是我们的twoint，twoint在内存中呢，是从0xbff4331a开始的，也就是说，我们的pPointer指向了twoint所在的地址，&lt;/p&gt;
&lt;p&gt;注意，看一下左边四个方块前面的二进制数，转换成16进制就是0xbff4331a了&lt;/p&gt;
&lt;p&gt;因此，取指针所指向的值就是35698了。指针本身的值则是0xbff4331a，指针所在的位置是0xbff43314。&lt;/p&gt;
&lt;p&gt;参考文章：&lt;a href=&#34;http://linuxconfig.org/c-understanding-pointers&#34;&gt;C++ : Understanding pointers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;另一个呢是关于引用的实现原理&lt;/p&gt;
&lt;p&gt;大家都知道，引用就是别名，比如下面这段代码&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

int main() {
   int number = 88;          // 定义一个int变量
   int &amp;amp; refNumber = number; // 声明并初始化一个引用
                             // 现在他们都表示了同一个值

   cout &amp;lt;&amp;lt; number &amp;lt;&amp;lt; endl;    // 打印number的值 (88)
   cout &amp;lt;&amp;lt; refNumber &amp;lt;&amp;lt; endl; // 打印引用的值 (88)

   refNumber = 99;            // 给refNumber重新赋一个值
   cout &amp;lt;&amp;lt; refNumber &amp;lt;&amp;lt; endl;
   cout &amp;lt;&amp;lt; number &amp;lt;&amp;lt; endl;    // number的值也就变成了 (99)

   number = 55;               // 重新给number赋一个值
   cout &amp;lt;&amp;lt; number &amp;lt;&amp;lt; endl;
   cout &amp;lt;&amp;lt; refNumber &amp;lt;&amp;lt; endl; // refNumber也就变成了(55)
}&lt;/pre&gt;
&lt;p&gt;输出结果肯定一目了然，其中的原理想过没&lt;/p&gt;</description>
    </item>
    <item>
      <title>倒水问题求解(C&#43;&#43;)</title>
      <link>http://blog.leaver.me/2013/05/15/%E5%80%92%E6%B0%B4%E9%97%AE%E9%A2%98%E6%B1%82%E8%A7%A3c/</link>
      <pubDate>Wed, 15 May 2013 18:37:24 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/05/15/%E5%80%92%E6%B0%B4%E9%97%AE%E9%A2%98%E6%B1%82%E8%A7%A3c/</guid>
      <description>&lt;p&gt;明天要去参加微软面试，不求顺利，但求体验。&lt;/p&gt;
&lt;p&gt;这个题目答题的意思是:&lt;/p&gt;
&lt;p&gt;给你一个容量为A升的桶和一个容量为B升的桶，水不限使用，要求精确得到Q升水.请说明步骤&lt;/p&gt;
&lt;p&gt;当数字比较小的时候,我们可以通过大脑穷举来得到结果,但这里有两个问题,当数字很大的时候怎么解?题目给定的数据是否有解?&lt;/p&gt;
&lt;p&gt;首先判断是否有解?&lt;/p&gt;
&lt;p&gt;题目可以理解为,x为用A的次数,y为用B的次数,Q为目标值&lt;/p&gt;
&lt;p&gt;Q = A * x + B * y
Q =目标值.&lt;/p&gt;
&lt;p&gt;Q必须是 Gcd(A,B)(也就是A,B的最大公约数)的倍数,否则无解,如果 Gcd(A,B) == 1, 任何Q都是可解的&lt;/p&gt;
&lt;p&gt;最简单的方法就是把A的水不断的向B中倒(B向A中倒也行),知道得到最终结果,如果桶满了,就清空该桶.举个例子&lt;/p&gt;
&lt;p&gt;A = 3, B = 4 并且 Q = 2
重复得从 A-&amp;gt;B&lt;/p&gt;
&lt;p&gt;A B&lt;/p&gt;
&lt;h6&gt;&lt;/h6&gt;
&lt;p&gt;0 0
4 0
1 3
1 0
0 1
4 1
2 3 &amp;lt;-A桶中得到2了&lt;/p&gt;
&lt;p&gt;试试从  B-&amp;gt;A&lt;/p&gt;
&lt;p&gt;A B&lt;/p&gt;
&lt;h5&gt;&lt;/h5&gt;
&lt;p&gt;0 0
0 3
3 0
3 3
4 2 &amp;lt;- B中也得到了2
但是注意,从 B-&amp;gt;A 比从 A-&amp;gt;B快哦&lt;/p&gt;
&lt;p&gt;然后我贴出代码&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &#34;stdafx.h&#34;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include&amp;lt;string&amp;gt;

using namespace std;

//热门智力题 - 打水问题
//基本思想：用A桶容量的倍数对B桶的容量进行取余。
//指导方针：不断用A桶装水倒入B桶，B桶满了立即清空
//每次判断下二个桶中水的容量是否等于指定容量。
const string OPERATOR_NAME[7] = {
	&#34;装满A桶&#34;,
	&#34;装满B桶&#34;,
	&#34;将A桶清空&#34;,
	&#34;将B桶清空&#34;,
	&#34;A桶中水倒入B桶&#34;,
	&#34;B桶中水倒入A桶&#34;,
	&#34;成功得到结果&#34;
};
int max(int a,int b)
{
	return a&amp;gt;b?a:b;
}
int gcd(int m,int n)
{
	int temp,p,r;
	//n存放最小数，m存放最大数
	if(n&amp;gt;m){
		temp = n;
		n = m;
		m = temp;
	}
	p=n*m;//先取得两个数的积
	while(n!=0){
		r=m%n;
		m=n;
		n=r;
	}
return m;
}
int _tmain(int argc, _TCHAR* argv[])
{
	int    a_capacity, b_capacity, goal_capacity;
	vector&amp;lt;string&amp;gt; record;       //记录操作过程
	int a_water, b_water;

	cout&amp;lt;&amp;lt;&#34;请输入A桶容量，B桶容量，目标容量Q：&#34;;
	cin&amp;gt;&amp;gt;a_capacity&amp;gt;&amp;gt;b_capacity&amp;gt;&amp;gt;goal_capacity;
	a_water = b_water = 0; //A桶，B桶中有多少升水

	//判断是否一定可解
	if (a_capacity&amp;lt;=0 || b_capacity&amp;lt;=0 || goal_capacity&amp;lt;=0)
	{
		cout&amp;lt;&amp;lt;&#34;请保证所以容量大于0&#34;&amp;lt;&amp;lt;endl;
		return -1;
	}
	if (goal_capacity&amp;gt;max(a_capacity,b_capacity))
	{
		cout&amp;lt;&amp;lt;&#34;要量出的容量应该小于其中桶容量&#34;&amp;lt;&amp;lt;endl;
		return -2;
	}
	//如果可解则解之
	if(goal_capacity%gcd(a_capacity,b_capacity)==0)
	{
		//存放临时的字符串构造
		char szTemp[30];
		while (true)
		{
			if (a_water == 0)//A桶没水,就装满水
			{
				a_water = a_capacity;
				sprintf(szTemp, &#34;         A:%d  B:%d&#34;, a_water, b_water);
				record.push_back(OPERATOR_NAME[0] + szTemp);//先填满 A桶
			}
			else
			{
				//如果A桶的水比(B桶容量-B桶的水)要多，也就是多于没装满的B桶空出来的部分，A桶会剩下
				if (a_water &amp;gt; b_capacity - b_water)
				{
					//A桶向B桶倒水直到B桶满，此时A桶的水==A桶的水+B桶的水-B桶容量
					a_water = a_water + b_water- b_capacity;
					b_water = b_capacity;		 //B桶的水装满了
					sprintf(szTemp, &#34;  A:%d  B:%d&#34;, a_water, b_water); 
					record.push_back(OPERATOR_NAME[4] + szTemp);//A-&amp;gt;B	
					if (a_water == goal_capacity)
						break;
					b_water = 0;			//将B桶清空
					sprintf(szTemp, &#34;       A:%d  B:%d&#34;, a_water, b_water); 
					record.push_back(OPERATOR_NAME[3] + szTemp);
				}
				else
				{
					//A桶小于装满B桶需要的水，此时B桶的水==A桶的水+B桶的水
					b_water += a_water;	
					a_water = 0;
					sprintf(szTemp, &#34;  A:%d  B:%d&#34;, a_water, b_water);
					record.push_back(OPERATOR_NAME[4] + szTemp);//A-&amp;gt;B
					if (b_water == goal_capacity) 
						break;
				}
			}
		}
		record.push_back(OPERATOR_NAME[6]);	//break出来说明成功了
		cout&amp;lt;&amp;lt;&#34;\n---------------------------------------------------&#34;&amp;lt;&amp;lt;endl;
		cout&amp;lt;&amp;lt;&#34;以下下是一种方案&#34;&amp;lt;&amp;lt;endl;
		vector&amp;lt;string&amp;gt;::iterator pos;
		for (pos = record.begin(); pos != record.end(); pos++)
			cout&amp;lt;&amp;lt;*pos&amp;lt;&amp;lt;endl;
		cout&amp;lt;&amp;lt;&#34;---------------------------------------------------&#34;&amp;lt;&amp;lt;endl;
	}
	else
	{
		cout&amp;lt;&amp;lt;&#34;此情况下无解&#34;&amp;lt;&amp;lt;endl;
	}

	return 0;
}&lt;/pre&gt;
&lt;p&gt;运行结果如下：&lt;/p&gt;</description>
    </item>
    <item>
      <title>一道笔试指针题目详解</title>
      <link>http://blog.leaver.me/2013/04/17/%E4%B8%80%E9%81%93%E7%AC%94%E8%AF%95%E6%8C%87%E9%92%88%E9%A2%98%E7%9B%AE%E8%AF%A6%E8%A7%A3/</link>
      <pubDate>Wed, 17 Apr 2013 08:34:39 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/04/17/%E4%B8%80%E9%81%93%E7%AC%94%E8%AF%95%E6%8C%87%E9%92%88%E9%A2%98%E7%9B%AE%E8%AF%A6%E8%A7%A3/</guid>
      <description>&lt;p&gt;看到本题是在搜狗某年的笔试题上,看也没人给出非常详细的讲解,直接给出了答案,我来尝试写一写,&lt;/p&gt;
&lt;p&gt;貌似本题来源自&amp;lt;**The C Puzzle Book&amp;gt; ，**搜狗也只是换了一下字符串，直接看题吧&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &amp;lt;stdio.h&amp;gt;
char *c[]={&#34;ENTNG&#34;, &#34;NST&#34;,&#34;AMAZI&#34;,&#34;FIRBE&#34;};
char** cp[]={c+3, c+2, c+1, c};
char ***cpp= cp;
int main() {
    printf(&#34;%s&#34;,**++cpp);
    printf(&#34;%s &#34;,*--*++cpp+3);
    printf(&#34;%s&#34;,*cpp[-2]+3);
    printf(&#34;%s&#34;,cpp[-1][-1]+1);
}&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;span style=&amp;quot;font-family: Georgia, &#39;Times New Roman&#39;, &#39;Bitstream Charter&#39;, Times, serif; font-size: 13px; line-height: 19px;&amp;quot;&amp;gt;请写出程序的执行结果....&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;首先从左到右看：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;char *c[]= {
              &#34;ENTNG&#34;, 
              &#34;NST&#34;,
              &#34;AMAZI&#34;,
              &#34;FIRBE&#34;
            };&lt;/pre&gt;
&lt;p&gt;*c[] 是一个字符，因此，c[]是指向该字符，c就是一个数组（数组的内容为指向字符的指针），c已经被初始化了.&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;char** cp[]={c+3, c+2, c+1, c};&lt;/pre&gt;
&lt;p&gt;再看第二行，**cp[]是一个字符，*cp[]就是一个指针，指向该字符，cp[]就是一个指针，指向该指针，而cp就成为了指针数组，内容是指向字符的指针的指针。并且通过c的元素进行了初始化&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;char ***cpp= cp;&lt;/pre&gt;
&lt;p&gt;第三行，***cpp是一个字符，**cpp指向该字符，*cpp指向该指针，cpp就指向该字符的指针的指针.&lt;/p&gt;
&lt;p&gt;然后我画一张图表示初始的情况看看&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/35001_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ec5c34f9784a9f2a30d7a044ee954099a6e32e78.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后对于下面的输出语句，通过操作符优先级使用括号来区分一下：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;*(*(++cpp));&lt;/pre&gt;
&lt;p&gt;这个嘛，就是把cpp后移(注意cpp已经改变了)然后就指向了cp[1]，然后两次取其值即可得到AMAZI&lt;/p&gt;
&lt;p&gt;推导过程如下：&lt;/p&gt;
&lt;address&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;++cpp -&amp;gt; cp[1]       // cp[1] -&amp;gt; c+2
++cpp = &amp;amp;cp[1]       // &amp;amp;(c+2)
*++cpp = *(&amp;amp;c+2)     //  c[2]
**++cpp = *&amp;amp;c[2]&lt;/pre&gt;
&lt;/address&gt;然后看第二个
&lt;pre class=&#34;lang:default decode:true&#34;&gt;(*(--(*(++cpp))))+3;&lt;/pre&gt;
加括号后如上，cpp再加一，就指向了cp[2],取一次值（也就是*号）就变成了c[1],然后--c[1]就指向了c[0],取值就成了c[0]的地址，然后地址+3，就是NG了
&lt;pre class=&#34;lang:default decode:true&#34;&gt;(*(cpp[-2]))+3;&lt;/pre&gt;
上面，cpp指向cp[2]了，然后呢，cpp[-2] 相当于*(cpp-2)，间接引用cp[2]，这样cpp[-2]就指向了cp[0]了，然后，就是FIRBE了,加3就是BE了
&lt;p&gt;最后&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;(cpp[-1][-1])+1;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;cpp还是之前的cp[2]，cpp[-1][-1]相当于*(*(cpp-1)-1),先减1指向了cp[1],取一次值就是c[2]了，然后c[2]-1就成为c[1]了，然后+1之后就是ST了.&lt;/p&gt;
&lt;p&gt;所以，最后输出就是&lt;/p&gt;
&lt;p&gt;AMAZINGBEST&lt;/p&gt;
&lt;p&gt;错误之处还望指正.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>模板优先级队列及堆排序(C&#43;&#43;实现)</title>
      <link>http://blog.leaver.me/2013/04/16/%E6%A8%A1%E6%9D%BF%E4%BC%98%E5%85%88%E7%BA%A7%E9%98%9F%E5%88%97%E5%8F%8A%E5%A0%86%E6%8E%92%E5%BA%8Fc-%E5%AE%9E%E7%8E%B0/</link>
      <pubDate>Tue, 16 Apr 2013 08:42:58 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/04/16/%E6%A8%A1%E6%9D%BF%E4%BC%98%E5%85%88%E7%BA%A7%E9%98%9F%E5%88%97%E5%8F%8A%E5%A0%86%E6%8E%92%E5%BA%8Fc-%E5%AE%9E%E7%8E%B0/</guid>
      <description>&lt;p&gt;模板优先级队列，数组实现，再熟悉一下常用算法，同时简单的堆排序应用&lt;/p&gt;
&lt;p&gt;写了一个是队列自增长，另一个为了演示我还添加了一个叫做FillPq的方法，这个方法可以使用一个数组直接填充到优先级队列里，此时，优先级队列并不优先，然后进行下滤调整，之后建堆完成，输出即可&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &#34;stdafx.h&#34;

template&amp;lt; class T&amp;gt;
class PriorityQueue
{
private:
	 T *pq;
	 int N;
	 int capacity;
public:
	PriorityQueue(void);
	~PriorityQueue(void);
	void Insert(T x);
	T DelTop();
	void Swim(int k);
	void Sink(int k);
	bool Less(int i,int j);
	void Swap(int i,int j);
	bool Resize();
	void FillPq(T arr[],int size);
};

template&amp;lt; class T&amp;gt;
void PriorityQueue&amp;lt;T&amp;gt;::FillPq( T arr[],int size )
{
	N=size;
	capacity=2*size;
	for (int i=0;i&amp;lt;size;i++)
	{
		pq[i+1]=arr[i];
	}
}

template&amp;lt; class T&amp;gt;
PriorityQueue&amp;lt;T&amp;gt;::PriorityQueue(void)
{
	pq=new T[10];
	N=0;
	capacity=10;
}

template&amp;lt; class T&amp;gt;
void PriorityQueue&amp;lt;T&amp;gt;::Insert( T x )
{
	if (N==capacity)
	{
		Resize();
	}
	pq[++N]=x;
	Swim(N);
}

template&amp;lt; class T&amp;gt;
T PriorityQueue&amp;lt;T&amp;gt;::DelTop()
{
	T max=pq[1];
	Swap(1,N--);
	Sink(1);
	pq[N+1]=NULL;
	return max;
}
//下滤
template&amp;lt; class T&amp;gt;
void PriorityQueue&amp;lt;T&amp;gt;::Sink( int k )
{
	while (2*k&amp;lt;=N)
	{
		int j=2*k;
		if (j&amp;lt;N &amp;amp;&amp;amp; Less(j,j+1))
		{
			j++;
		}
		if (!Less(k,j))
		{
			break;
		}
		Swap(k,j);
		k=j;
	}
}
//上浮
template&amp;lt; class T&amp;gt;
void PriorityQueue&amp;lt;T&amp;gt;::Swim( int k )
{
	while (k&amp;gt;1 &amp;amp;&amp;amp; Less(k/2,k))
	{
		Swap(k,k/2);
	}
}

template&amp;lt; class T&amp;gt;
void PriorityQueue&amp;lt;T&amp;gt;::Swap( int i,int j )
{
	T temp=pq[i];
	pq[i]=pq[j];
	pq[j]=temp;
}

template&amp;lt; class T&amp;gt;
bool PriorityQueue&amp;lt;T&amp;gt;::Less( int i,int j )
{
	return pq[i]&amp;lt;pq[j];
}

template&amp;lt; class T&amp;gt;
bool PriorityQueue&amp;lt;T&amp;gt;::Resize()
{
	T *newPq=new T[capacity*2];
	capacity=capacity*2;
	for (int i=1;i&amp;lt;=N;i++)
	{
		newPq[i]=pq[i];
	}
	pq=newPq;
	return true;
}

template&amp;lt; class T&amp;gt;
PriorityQueue&amp;lt;T&amp;gt;::~PriorityQueue(void)
{
}&lt;/pre&gt;
&lt;p&gt;然后是堆排序&lt;/p&gt;</description>
    </item>
    <item>
      <title>模板栈以及中缀表达式求值(C&#43;&#43;实现)</title>
      <link>http://blog.leaver.me/2013/04/11/%E6%A8%A1%E6%9D%BF%E6%A0%88%E4%BB%A5%E5%8F%8A%E4%B8%AD%E7%BC%80%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%B1%82%E5%80%BCc-%E5%AE%9E%E7%8E%B0/</link>
      <pubDate>Thu, 11 Apr 2013 18:50:25 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/04/11/%E6%A8%A1%E6%9D%BF%E6%A0%88%E4%BB%A5%E5%8F%8A%E4%B8%AD%E7%BC%80%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%B1%82%E5%80%BCc-%E5%AE%9E%E7%8E%B0/</guid>
      <description>&lt;p&gt;栈直接用链表实现，这个比较简单，不多说，不过C++写程序，IDE的错误检测不是很给力。&lt;/p&gt;
&lt;p&gt;至于给定一个中缀表达式，如何不转换成后缀表达式，直接求值，方法就是使用两个栈，一个操作符栈，一个操作数栈，然后从左到右扫描表达式，我这里中缀表达式计算实现的很简单，不完整，大家可以扩展。栈的实现是我想写的，思路如下：&lt;/p&gt;
&lt;p&gt;1.如何是操作数，压入操作数栈&lt;/p&gt;
&lt;p&gt;2.如果是操作符，压入操作符栈&lt;/p&gt;
&lt;p&gt;3.如果是左括号，直接忽略&lt;/p&gt;
&lt;p&gt;4.如果是有括号，弹出操作符栈栈顶元素，然后弹出操作数栈两个元素，进行操作以后结果压入操作数栈&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;看个图就好了&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/34863_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/d0b2eed86d2ba2b987d3e5db380b9a452e8f5f87.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;最后给出栈顶实现代码&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &#34;stdafx.h&#34;
#pragma region Node定义

template &amp;lt;class T&amp;gt;
class Node
{
	template&amp;lt;class T&amp;gt; 
	friend class Stack;
private:
	T m_data;
	Node *pNextNode;
public:
	Node();
	Node(T d);
};

template &amp;lt;class T&amp;gt;
Node&amp;lt;T&amp;gt;::Node()
{
	m_data=default(T);
	pNextNode=NULL;
}
template &amp;lt;class T&amp;gt;
Node&amp;lt;T&amp;gt;::Node(T d)
{
	m_data=d;
	pNextNode=NULL;
}
#pragma endregion 

#pragma region Stack定义

template &amp;lt;class T&amp;gt;
class Stack
{

private:
	Node&amp;lt;T&amp;gt; *m_pTopNode;
	int m_nNodeCount;
public:
	Stack();
	~Stack();
	bool IsEmpty();
	bool Push(T e);
	T Pop();
	int Size();
};

template &amp;lt;class T&amp;gt;
Stack&amp;lt;T&amp;gt;::Stack() : m_pTopNode(NULL),m_nNodeCount(0)
{
}

template &amp;lt;class T&amp;gt;
Stack&amp;lt;T&amp;gt;::~Stack()
{
	while (!IsEmpty())
	{
		Node&amp;lt;T&amp;gt; *pTempNode = m_pTopNode;
		m_pTopNode = m_pTopNode-&amp;gt;pNextNode;
		delete (pTempNode);
		pTempNode = NULL;
	}
	m_nNodeCount = 0;
	m_pTopNode = NULL;
}

template &amp;lt;class T&amp;gt;
bool Stack&amp;lt;T&amp;gt;::IsEmpty()
{
	return (m_pTopNode == NULL);
}

template &amp;lt;class T&amp;gt;
bool Stack&amp;lt;T&amp;gt;::Push(T e )
{
	Node&amp;lt;T&amp;gt; *pNewNode = new Node&amp;lt;T&amp;gt;(e);
	if (NULL == pNewNode)     {
		return false;
	}

	if(! IsEmpty()) {
		pNewNode-&amp;gt;pNextNode = m_pTopNode;
	}
	m_pTopNode = pNewNode;
	m_nNodeCount ++;

	return true;
}

template &amp;lt;class T&amp;gt;
T Stack&amp;lt;T&amp;gt;::Pop()
{
	if(IsEmpty()) {
		return T(-1);
	}
	T e;
	e = m_pTopNode-&amp;gt;m_data;
	Node&amp;lt;T&amp;gt; *pNode = m_pTopNode;
	m_pTopNode = m_pTopNode-&amp;gt;pNextNode;
	delete (pNode);
	m_nNodeCount--;

	return e;
}

template &amp;lt;class T&amp;gt;
int Stack&amp;lt;T&amp;gt;::Size()
{
	return m_nNodeCount;
}
#pragma endregion&lt;/pre&gt;
&lt;p&gt;然后是main函数代码&lt;/p&gt;</description>
    </item>
    <item>
      <title>并查集(C&#43;&#43;实现)</title>
      <link>http://blog.leaver.me/2013/04/11/%E5%B9%B6%E6%9F%A5%E9%9B%86c-%E5%AE%9E%E7%8E%B0/</link>
      <pubDate>Thu, 11 Apr 2013 08:45:38 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/04/11/%E5%B9%B6%E6%9F%A5%E9%9B%86c-%E5%AE%9E%E7%8E%B0/</guid>
      <description>&lt;p&gt;并查集这个很有意思，并查集是一种树型的数据结构，用于处理一些不相交集合（Disjoint Sets）的合并及查询问题。昨天看书看到了，然后用C++简单实现了下。在Dijkstra算法中，用来判断两个顶点是否在同一个集合里。&lt;/p&gt;
&lt;p&gt;里面定义了两个类，都是并查集，一个是QuickFind，查找很快，一个是QuickUnion，合并较快。写了一些注释，有一些优化的提示.看代码吧，有什么问题指出来吧。&lt;/p&gt;
&lt;p&gt;QuickFind的实现&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &#34;QuickFind.h&#34;

QuickFind::QuickFind(int N)
{
	size=N;
	id=new int[N];
	for(int i=0;i&amp;lt;N;i++)
	{
		id[i]=i;
	}
}

bool QuickFind::Find(int p,int q)
{
	return id[p]==id[q];
}

void QuickFind::Unite(int p,int q)
{
	int pid=id[p];
	for(int i=0;i&amp;lt;size;i++)
		if(id[i]==pid)
			id[i]=id[q];

}
QuickFind::~QuickFind(void)
{
	delete []id;
}&lt;/pre&gt;
&lt;p&gt;QuickUnion的实现&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &#34;QuickUnion.h&#34;

QuickUnion::QuickUnion(int N)
{
	size=N;
	id=new int[N];
	for(int i=0;i&amp;lt;N;i++)
	{
		id[i]=i;
	}
}
int QuickUnion::root(int i)
{
	while (i!=id[i])
	{
		//id[i]=id[id[i]]; 若添加这句话则为压缩路径
		i=id[i];
	}
	return i;
}
bool QuickUnion::Find(int p,int q)
{
	return root(p)==root(q);
}

void QuickUnion::Unite(int p,int q)
{
	//将p的根挂在q的根上，
	//这样会导此数变高，若需要优化，需要设置另一个
	//数组sz[]，sz[i]表示所以根为i的节点的数目，然后将
	//小树靠在大树上

	/*
	int i=root(p);
	int j=root(q);
	if(sz[i]&amp;lt;sz[j])
	{
		id[i]=j;sz[j]+=sz[i];
	}
	else
	{
		id[j]=i;sz[i]+=sz[j];
	}*/
	int rootp=root(p);
	int rootq=root(q);
	id[rootp]=rootq;
}
QuickUnion::~QuickUnion(void)
{
	delete []id;
}&lt;/pre&gt;
&lt;p&gt;参考文档(英文)：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=436984&amp;amp;uk=1493685990&#34;&gt;UnionFind.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;工程代码下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=436978&amp;amp;uk=1493685990&#34;&gt;并查集Demo&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>和
浅析</title>
      <link>http://blog.leaver.me/2013/04/05/%E5%92%8C-%E6%B5%85%E6%9E%90/</link>
      <pubDate>Fri, 05 Apr 2013 13:29:04 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/04/05/%E5%92%8C-%E6%B5%85%E6%9E%90/</guid>
      <description>&lt;p&gt;这两个转义字符最初学习C++的时候看到了,当时没多想，后来某一天突然想起来，回车不就是换行吗？这不是多此一举吗？今天又看到，索性查了下相关资料，整理一下，留作记录.&lt;/p&gt;
&lt;p&gt;关于“回车”（carriage return）和“换行”（line feed）这两个概念的来历和区别。&lt;/p&gt;
&lt;p&gt;在计算机还没有出现之前，有一种叫做电传打字机（Teletype Model 33）的玩意，每秒钟可以打10个字符。但是它有一个问题，就是打完一行换行的时候，要用去0.2秒，正好可以打两个字符。要是在这0.2秒里面，又有新的字符传过来，那么这个字符将丢失。&lt;/p&gt;
&lt;p&gt;于是，研制人员想了个办法解决这个问题，就是在每行后面加两个表示结束的字符。一个叫做“回车”，告诉打字机把打印头定位在左边界；另一个叫做“换行”，告诉打字机把纸向下移一行（这句的意思是把纸向上拉，然后打印头就定位到了下一行），可以想象一下，这个打印头只能在一个固定的水平线上左右移动，而不能上下移动，我们通过移动纸来完成打印下一行。&lt;/p&gt;
&lt;p&gt;不明白的我在youtube上找到一个这种打字机的演示视频，为了方便读者观看，我提供一个&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=428006&amp;amp;uk=1493685990&#34;&gt;下载地址&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;后来，计算机发明了，这两个概念也就被般到了计算机上。那时，存储器很贵，一些科学家认为在每行结尾加两个字符太浪费了，加一个就可以。于是，就出现了分歧。&lt;/p&gt;
&lt;p&gt;Unix系统里，每行结尾只有&amp;quot;&amp;lt;换行&amp;gt;&amp;quot;，即&amp;quot;\n&amp;quot;；&lt;/p&gt;
&lt;p&gt;Windows系统里面，每行结尾是&amp;quot;&amp;lt;换行&amp;gt;&amp;lt;回车&amp;gt;&amp;quot;，即&amp;quot;\n\r&amp;quot;；&lt;/p&gt;
&lt;p&gt;Mac系统里，每行结尾是&amp;quot;&amp;lt;回车&amp;gt;&amp;quot;，不过mac基于unix，所以换行也应该是可以的。&lt;/p&gt;
&lt;p&gt;一个直接后果是，Unix/Mac系统下的文件在Windows里打开的话，所有文字会变成一行；而Windows里的文件在Unix/Mac下打开的话，在每行的结尾可能会多出一个^M符号。这个如果你在windows下使用vim也会发现这个情况&lt;/p&gt;
&lt;p&gt;用C++来说明&lt;/p&gt;
&lt;p&gt;如：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;int main() 
{
   cout &amp;lt;&amp;lt; &#34;leaver.me&#34; &amp;lt;&amp;lt; &#34;\r&#34; &amp;lt;&amp;lt; &#34;bystander&#34; ;
   return 0;
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;最后只显示 bystander 而 leaver.me 背覆盖了&lt;/p&gt;
&lt;p&gt;\n 是换行，系统会将其替换成回车＋换行 把光标 先移到 行首 然后换到下一行 也就是 下一行的行首拉&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;int main() 
{
   cout &amp;lt;&amp;lt; &#34;leaver.me&#34; &amp;lt;&amp;lt; &#34;\n&#34; &amp;lt;&amp;lt; &#34;bystander&#34; ;
   return 0;
}&lt;/pre&gt;
&lt;p&gt;则 显示&lt;/p&gt;
&lt;p&gt;leaver.me&lt;/p&gt;
&lt;p&gt;bystander&lt;/p&gt;
&lt;p&gt;一句话，这看起来是一个历史遗留问题&amp;hellip;&amp;hellip;&lt;/p&gt;</description>
    </item>
    <item>
      <title>[藏]关于B树的一篇文章</title>
      <link>http://blog.leaver.me/2013/04/01/%E8%97%8F%E5%85%B3%E4%BA%8Eb%E6%A0%91%E7%9A%84%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0/</link>
      <pubDate>Mon, 01 Apr 2013 18:12:37 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/04/01/%E8%97%8F%E5%85%B3%E4%BA%8Eb%E6%A0%91%E7%9A%84%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0/</guid>
      <description>&lt;p&gt;很多人对B树的理解有很多错误，我看的最多的就是有人混淆二叉树（Binary Tree）和B树（B-Tree）,二叉树是不用简称，也就是BT的，而特殊一点的二叉搜索树才会用BST(Binary Search Tree),至于B-树和B树，这两个其实一样的，英文都是(B-Tree)，注意看中间的-号，这个是国内翻译的问题.所以大家不要被误导.&lt;/p&gt;
&lt;p&gt;Rudolf Bayer 和 Ed McCreight 于1972年，在Boeing Research Labs 工作时发明了B 树，但是他们没有解释B 代表什么意义（如果有的话）.Douglas Comer 解释说: 两位作者从来都没解释过B树的原始意义。我个人觉得很有可能是他的名字，程序员对其作品的一种情结吧.&lt;/p&gt;
&lt;p&gt;这篇文章来自国外,是某大学的CS课程在线的,由于有时候无法访问，我直接提供PDF版,对其构造过程非常清晰.非常非常好的B树教程,图示很多,就不翻译了,强烈推荐阅读！&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=404077&amp;amp;uk=1493685990&#34;&gt;B树讲解&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>简单扩展方法增强代码可读性</title>
      <link>http://blog.leaver.me/2012/10/04/%E7%AE%80%E5%8D%95%E6%89%A9%E5%B1%95%E6%96%B9%E6%B3%95%E5%A2%9E%E5%BC%BA%E4%BB%A3%E7%A0%81%E5%8F%AF%E8%AF%BB%E6%80%A7/</link>
      <pubDate>Thu, 04 Oct 2012 09:03:48 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/04/%E7%AE%80%E5%8D%95%E6%89%A9%E5%B1%95%E6%96%B9%E6%B3%95%E5%A2%9E%E5%BC%BA%E4%BB%A3%E7%A0%81%E5%8F%AF%E8%AF%BB%E6%80%A7/</guid>
      <description>&lt;p&gt;本文技术含量不高，但是思路可以借鉴。。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;介绍&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;当你处理计时器，时间间隔，或是其他关于日期的计算的时候。你必然会使用TimeSpan类。&lt;/p&gt;
&lt;p&gt;我觉得写出下面的代码可读性并不好。。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;// 1个表示5小时的时间间隔
var theTimespan = new TimeSpan(0, 5, 0, 0, 0);&lt;/pre&gt;
&lt;p&gt;而下面的代码就要好一些&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;//一个表示5小时的时间间隔
var theTimespan = 5.Hours();&lt;/pre&gt;
&lt;p&gt;** 扩展方法**&lt;/p&gt;
&lt;p&gt;使用这些扩展了int类的方法。可以使得创建TimeSpan可读性更好&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public static TimeSpan Days(this int value)
{
    return new TimeSpan(value, 0, 0, 0, 0);
}

public static TimeSpan Years(this int value)
{
    var dt = DateTime.Now.AddYears(value);
    return (dt - DateTime.Now).Duration();
}

public static TimeSpan Hours(this int value)
{
    return new TimeSpan(0, value, 0, 0, 0);
}

public static TimeSpan Minutes(this int value)
{
    return new TimeSpan(0, 0, value, 0, 0);
}

public static TimeSpan Seconds(this int value)
{
    return new TimeSpan(0, 0, 0, value, 0);
}

public static TimeSpan Milliseconds(this int value)
{
    return new TimeSpan(0, 0, 0, 0, value);
}&lt;/pre&gt;
&lt;p&gt;许可&lt;/p&gt;
&lt;p&gt;本文所有源代码包括文件在CPOL下授权。。&lt;/p&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;http://www.codeproject.com/Tips/469097/Simple-extension-methods-for-code-readability&#34;&gt;Simple-extension-methods-for-code-readability&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;著作权声明：本文由&lt;a href=&#34;http://leaver.me/&#34;&gt;http://leaver.me&lt;/a&gt; 翻译，欢迎转载分享。请尊重作者劳动，转载时保留该声明和作者博客链接，谢谢！&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>11个高效的VS调试技巧</title>
      <link>http://blog.leaver.me/2012/10/03/11%E4%B8%AA%E9%AB%98%E6%95%88%E7%9A%84vs%E8%B0%83%E8%AF%95%E6%8A%80%E5%B7%A7/</link>
      <pubDate>Wed, 03 Oct 2012 10:45:15 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/03/11%E4%B8%AA%E9%AB%98%E6%95%88%E7%9A%84vs%E8%B0%83%E8%AF%95%E6%8A%80%E5%B7%A7/</guid>
      <description>&lt;p&gt;&lt;strong&gt;介绍&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;调试是软件开发周期中的一个很重要的部分，有时很有挑战性，有时候则让程序员迷惑，有时候让程序员发疯，但是。可以肯定的是，对于任何不是太那个微不足道的程序来说，调试是不可避免的。近年来，调试工具的发展已经使得很多调试任务简单省时了。&lt;/p&gt;
&lt;p&gt;本文总结了十个调试技巧，当你使用VS的时候可以节省你很多时间。&lt;/p&gt;
&lt;p&gt;1. 悬停鼠标查看表达式&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27679_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/5b9e01a5158e02f8079c7dc331f56110f3e0b82d.png&#34; title=&#34;1&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;调试有时候很有挑战性，当你步入一个函数想看看哪块出错的时候，查看调用栈来想想值是从哪来的。另一些情况下，则需要添加一些监视表达式，或者查看局部变量列表，这通常还是花费一些时间的，但是。如果你把你鼠标指向你感兴趣的一个变量。你会发现事情简单多了。而且，类和结构体可以通过单击展开。这样。你就可以方便快捷的找到你想查看的变量了。&lt;/p&gt;
&lt;p&gt;2. 实时改变值
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27680_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/eade577f5ea39d3b970613ac3123610b67e427cb.png&#34; title=&#34;2&#34;&gt;&lt;/a&gt;
调试器不仅仅是一个分析程序崩溃或是异常结果的工具了，许多bug都可以通过步入新写的函数，检查函数是否如期望的那样运行来预防。有时候你可能会好奇“如果条件为真函数会正确运行吗”大多数情况下，根本不需要改变代码重启挑起，仅仅把鼠标悬停到一个变量上，双击值然后输入一个新值就可以了。。&lt;/p&gt;
&lt;p&gt;3．设置下一条语句
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27690_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/1c86cc15b16c98adc1563eb1660481fa249beaf0.png&#34; title=&#34;3&#34;&gt;&lt;/a&gt;
一个典型的调试情况就是通过单步跟踪分析为什么一个函数调用失败了。当你发现一个函数调用的另一个函数返回错误的时候你会怎么做？重启调试？有更好的方法。拖动这个黄色的语句标识到你想下一步执行的语句前就可以了。比如你刚才失败的那块，然后步入。简单，不是吗？&lt;/p&gt;
&lt;p&gt;4.编辑然后继续
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27682_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/8117d2025d49155485268fc1b56041e96cefaeac.png&#34; title=&#34;4&#34;&gt;&lt;/a&gt;
调试一个复杂的程序，或是一个插件的时候，在一个被调用很多次的函数处发现一个错误。但是不想浪费时间停下来，重新编译然后重新调试。没问题，仅仅在该处改正代码然后继续单步就可以。VS会修正程序然后继续调试不需要重启&lt;/p&gt;
&lt;p&gt;注意，编辑然后继续有大量的已知限制，首先，64位代码是不行的。如果他如果为你的C#程序工作。就去工程设置的生成选项，然后目标平台为x86.不要担心。发布版的目标平台和调试的时候是分开的。可以被设置为任何平台。。&lt;/p&gt;
&lt;p&gt;第二．编辑然后继续改变在一个方法里应该是局部的。。如果你改变了方法签名，添加一些新方法或是类。你就不得不重启程序了。或者撤销改变来继续。改变方法也包含lambda表达式隐式修改的自动生成的代理类，因此也不能继续。&lt;/p&gt;
&lt;p&gt;5.方便的监视窗口
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27683_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/a204da1e7bb82719b4a965da45d1cfcc51a90cd3.png&#34; title=&#34;5&#34;&gt;&lt;/a&gt;
大概现代的调试器都有一个监视窗口，无论如何。VS允许你简单的添加或移除变量。单击空行，输入你的表达式按下回车，或者是在不需要的表达式上按下Delete键就可以删除了。
而且。从监视窗口你不仅仅可以看到“正常”的变量。你可以输入$handles 来追踪你的程序打开了多少句柄（可以方便的修复内存泄漏） ，输入$err 可以看到上一个函数的错误码，然后使用工具-错误信息可以看到更详细的描述，或者输入@eax（64位是@rax）来查看包含函数返回值的寄存器。&lt;/p&gt;
&lt;p&gt;6.带注释的反汇编
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27684_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/d61b64ed0a189bec2f34f2faaf059916cce8e525.png&#34; title=&#34;6&#34;&gt;&lt;/a&gt;
使用交互式的反汇编模式可以使得优化程序的关键部分变得很容易，VS给出对应你代码每一行的汇编指令，并且运行单步运行。同时，可以在任何位置设置断点。而且，表达式的查看和修改也像在C++代码里一样&lt;/p&gt;
&lt;p&gt;7.带有栈的线程窗口
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27691_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/5b212033679007829bb5c0684d62ab8f27a0514b.png&#34; title=&#34;7&#34;&gt;&lt;/a&gt;
调试多线程的程序是痛苦的。。或者也可以是很有趣的。取决于你的调试器。VS2010真正优美的特性是线程窗口的栈视图，通过窗口的调用栈你可以方便的总览线程。&lt;/p&gt;
&lt;p&gt;8.条件断点
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27686_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/e93436bf72af22e533fe859971913a3d3c555789.png&#34; title=&#34;8&#34;&gt;&lt;/a&gt;
如果你尝试通过断点再现一个罕见的事件，该情况引发了一些严重的错误。你可以添加条件断点。定义一个断点的条件，然后如果条件不成立，VS会忽略该断点&lt;/p&gt;
&lt;p&gt;9.内存窗口
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27687_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/0cfda80c7dbe3d0c50bb5646155914b5e3f07f4f.png&#34; title=&#34;9&#34;&gt;&lt;/a&gt;
有些bug由不正确的结构体定义引起，忽略的对齐属性等等。查看内存中的内容可以定位然后修复bug。VS提供了一个放百年的内存窗口，可以把值以8/16/32/64位的形式展示。还有浮点值。也允许实时改变他们。就像在文本编辑器里一样。&lt;/p&gt;
&lt;p&gt;10.转到定义
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27688_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/3593aad0199fbed2f8faaef908e151a068e14d09.png&#34; title=&#34;10&#34;&gt;&lt;/a&gt;
这个特性不是直接关于调试的，而是关于浏览大项目的。如果你尝试找到一些不是你自己写的代码中的错误，快速知道“这个类型是什么”或者“这个函数是干嘛的”，可以节省很多时间，VS通过一个转到定义命令方便了你。&lt;/p&gt;
&lt;p&gt;11.命令窗口
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27689_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2af5b37764b18abe3ae34c1a67e4398721fbd04b.png&#34; title=&#34;11&#34;&gt;&lt;/a&gt;
第十一的技巧&lt;a href=&#34;http://www.codeproject.com/script/Membership/View.aspx?mid=4917930&#34;&gt;chaau&lt;/a&gt;已经建议过了。确实可以节省很多时间，VS支持命令窗口，可以通过，视图-其他窗口-命令窗口来启动。一旦激活，你可以输入不同的命令来自动化调试。举个例子。你可以通过如下命令 简单的模拟MFC COleDateTime 变量。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;? dt.Format(&#34;%Y-%m-%d %H:%M:%S&#34;)&lt;/pre&gt;
&lt;p&gt;许可
本文包括源代码和文件在CPOL下授权。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;http://www.codeproject.com/Articles/359801/10plus-powerful-debugging-tricks-with-Visual-Studi&#34;&gt;10plus-powerful-debugging-tricks-with-Visual-Studi&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;著作权声明：本文由&lt;a href=&#34;http://leaver.me/&#34;&gt;http://leaver.me&lt;/a&gt; 翻译，欢迎转载分享。请尊重作者劳动，转载时保留该声明和作者博客链接，谢谢！&lt;/p&gt;</description>
    </item>
    <item>
      <title>VS2010 编译安装boost库</title>
      <link>http://blog.leaver.me/2012/05/24/vs2010-%E7%BC%96%E8%AF%91%E5%AE%89%E8%A3%85boost%E5%BA%93/</link>
      <pubDate>Thu, 24 May 2012 11:39:55 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/24/vs2010-%E7%BC%96%E8%AF%91%E5%AE%89%E8%A3%85boost%E5%BA%93/</guid>
      <description>&lt;p&gt;实践是最好的办法。。学习C++，想试试线程，然后打算用boost库，结果boost库编译差点吓到我。。没看到比较完整的安装教程。。一直耽搁。今天动手。完成了。方法记录如下：
1.下载boost
从boost官网( &lt;a href=&#34;http://www.boost.org&#34;&gt;http://www.boost.org&lt;/a&gt; )上下载最新的boost版本，现在最新是1.49版本，解压到自定义目录(我解压到了D:/program files,最终的目录结构是D:\Program Files\boost_1_49_0)&lt;/p&gt;
&lt;p&gt;2.编译安装&lt;/p&gt;
&lt;p&gt;在D:\Program Files\boost_1_49_0的目录下，有一个bootstrap.bat文件，直接双击运行。就会在同目录生成b2.exe；bjam.exe两个文件。&lt;/p&gt;
&lt;p&gt;3.设定编译环境
修改user-config.jam (D:\Program Files\boost_1_49_0\tools\build\v2\user-config.jam) 的MSVC configuration&lt;/p&gt;
&lt;h1 id=&#34;msvc-configuration&#34;&gt;MSVC configuration&lt;/h1&gt;
&lt;h1 id=&#34;configure-msvc-default-version-searched-for-in-standard-locations-and-path&#34;&gt;Configure msvc (default version, searched for in standard locations and PATH).&lt;/h1&gt;
&lt;h1 id=&#34;using-msvc-&#34;&gt;using msvc ;&lt;/h1&gt;
&lt;p&gt;在上面这段的下面直接添加如下的文字。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;using msvc : 10.0 : :/wd4819/D_CRT_SECURE_NO_DEPRECATE/D_SCL_SECURE_NO_DEPRECATE/D_SECURE_SCL=0 ;&lt;/pre&gt;
&lt;p&gt;保存关闭。&lt;/p&gt;
&lt;p&gt;4.开始编译
点击开始-&amp;gt;所有程序-&amp;gt;“Microsoft Visual Studio 2010”，指向“Visual Studio tools(工具)”，然后单击“Visual Studio 2010 command prompt（命令提示）” 使用cd切换到D:\Program Files\boost_1_49_0目录。这个就不说了
然后输入如下的代码：&lt;/p&gt;
&lt;pre class=&#34;lang:sh decode:true  crayon-selected&#34;&gt;b2 toolset=msvc-10.0 architecture=x86 instruction-set=i686 address-model=32 link=static 
variant=debug,release threading=multi runtime-link=shared --without-python --without-mpi 
--without-wave --without-graph --without-math --without-serialization stage&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;解释一下命令的意思：
1.toolset：表示编译器工具，我安装的是VS2010，所以是msvc-10(如果你是VS2005，可以使用msvc-8.0 VS2008是msvc-9.0)
2.architecture：表示架构，也就是你的CPU架构，x86,x64，因为我安装的是win7 32位，所以使用了x86的架构
3.instruction-set：表示指令集，依然是8086指令集
4.address-model：表示地址长度为32位
5.link：表示生成动态/静态链接库，动态链接库是shared，静态链接库是static，一般都会编译成静态库，因为给出程序的时候打包boost的库会非常庞大
6.variant：表示生成的Debug或者release版本，一般情况下会两种版本都会编译出来的
7.threading：表示单/多线程编译，一般我们的程序都会用到多线程，所以选择了multi
8.runtime-link：表示动态/静态链接C/C++运行时库(C/C++ Runtime)，我们选择了动态链接
9.without/with：表示不需要编译/需要编译哪些库，一些自己不用的库可以无需编译
10.stage/install：stage表示只生成库文件(DLL和Lib)，install还会生成包含头文件的include目录，推荐使用stage，因为boost_1_49\boost中就是boost库完整的头文件，所以无需再拷贝一份出来。编译出来的库会放在stage文件夹中
这样一份完整的boost库就生成了，剩下就是直接使用到项目中了。&lt;/p&gt;
&lt;p&gt;其实编译的具体命令都是可以自己写的。如果你需要编译所有。只需要使用下面的这行代码
b2 &amp;ndash;toolset=msvc-10.0 &amp;ndash;build-type=complete
就可以了。&lt;/p&gt;
&lt;p&gt;不出问题的话。就开始编译了。。登个半个多小时吧。就会完成了。
5.设置vs
打开vs，新建一个工程。然后工程属性。配置属性-&amp;gt;C/C++ ，附加包含目录
填上
D:\Program Files\boost_1_49_0;%(AdditionalIncludeDirectories)
这个是最终的结果，你也可以手动添加&lt;/p&gt;
&lt;p&gt;在左侧选择链接器-&amp;gt;附加库目录，填上
D:\Program Files\boost_1_49_0\stage\lib;%(AdditionalLibraryDirectories)
就可以了。&lt;/p&gt;
&lt;p&gt;6.测试
在你新建的工程里输入如下的代码。运行成功就说明可以了&lt;/p&gt;
&lt;pre class=&#34;lang:c++ decode:true &#34;&gt;#include &amp;lt;boost/thread/thread.hpp&amp;gt;
#include &amp;lt;iostream&amp;gt;

void hello()
{
        std::cout &amp;lt;&amp;lt;
        &#34;Hello world, I&#39;m a thread!&#34;
        &amp;lt;&amp;lt; std::endl;
}

int main(int argc, char* argv[])
{
        boost::thread thrd(&amp;amp;hello);
        thrd.join();
        return 0;
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;参考：
&lt;a href=&#34;http://www.cppfans.org/1317.html&#34;&gt;http://www.cppfans.org/1317.html&lt;/a&gt;
&lt;a href=&#34;http://www.cnblogs.com/ComputerG/archive/2011/03/10/1979730.html&#34;&gt;http://www.cnblogs.com/ComputerG/archive/2011/03/10/1979730.html&lt;/a&gt;
&lt;a href=&#34;http://www.cppblog.com/shaker/archive/2011/11/30/33583.html&#34;&gt;http://www.cppblog.com/shaker/archive/2011/11/30/33583.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>快速排序算法</title>
      <link>http://blog.leaver.me/2012/05/19/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95/</link>
      <pubDate>Sat, 19 May 2012 09:04:40 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/19/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95/</guid>
      <description>&lt;pre lang=&#34;c&#34;&gt;
#include &lt;iostream&gt;
using namespace std;

//化分区间,找到最后元素的排序位置。并返回分隔的点（即最后一数据排序的位置）。
//划分的区间是[nBegin, nEnd). pData是保存数据的指针
int Partition(int* pData, int nBeging, int nEnd)
{
                int i = nBeging - 1;    //分隔符号，最后nD保存在这里
                --nEnd;
                int nD = pData[nEnd]; //比较的数据。
                int nTemp; // 交换用的临时数据

                //遍历数据比较，找到nD的位置，这里注意，比较结果是,
                //i的左边是小于等于nD的，i的右边是大于nD的
                for (int j = nBeging; j &lt; nEnd; ++j)
                {
                                if (pData[j] &lt;= nD)        //如果数据比要比较的小，则在该数据的左边，与i+1交换
                                {
                                                ++i;                //小于nD的数据多一个，所以要加1，i的左边数据都比nD小
                                                nTemp = pData[i];    //交换数据
                                                pData[i] = pData[j];
                                                pData[j] = nTemp;
                                }
                }

                //最后不要忘了吧nD和i+1交换，因为这里就是nD的位置咯。
                ++i;
                pData[nEnd] = pData[i];
                pData[i] = nD;

                return i;   //返回nD的位置，就是分割的位置。
}

//排序的递归调用。
int QuickSortRecursion(int* pData, int nBeging, int nEnd)
{
                if (nBeging &gt;= nEnd -1)        //如果区域不存在或只有一个数据则不递归排序
                {
                                return 1;
                }

                //这里因为分割的时候，分割点处的数据就是排序中他的位置。
                //也就是说他的左边的数据都小于等于他，他右边的数据都大于他。
                //所以他不在递归调用的数据中。
                int i = Partition(pData, nBeging, nEnd);        //找到分割点
                QuickSortRecursion(pData, nBeging, i);            //递归左边的排序
                QuickSortRecursion(pData, i + 1, nEnd);            //递归右边的排序
                return 1;
}

//快速排序
int QuickSort(int* pData, int nLen)
{
                //递归调用，快速排序。
                QuickSortRecursion(pData, 0, nLen);
                return 1;
}
int main()
{
                int nData[10] = {5,9,3,2,1,6,20,45,88,75};        //测试数据
                QuickSort(nData, 10);            //调用快速排序
                for (int i = 0; i &lt; 10; ++i)        //输出结果
                {
                                cout&lt;&lt;nData[i]&lt;&lt;&#34; &#34;;
                }
                cout&lt;&lt;endl;

                return 0;
}
&lt;/pre&gt;</description>
    </item>
    <item>
      <title>C&#43;&#43;回调函数</title>
      <link>http://blog.leaver.me/2012/05/09/c-%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0/</link>
      <pubDate>Wed, 09 May 2012 21:04:37 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/09/c-%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0/</guid>
      <description>&lt;p&gt;　　回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数，当这个指针被用为调用它所指向的函数时，我们就说这是回调函数。&lt;/p&gt;
&lt;p&gt;　　也就是说，回调函数它首先是一个函数，然后有一个指针指向它（该指针称为函数指针），在别的代码块中，通过这个函数指针调用了这个函数，仅此而已。&lt;/p&gt;
&lt;p&gt;　　下面给出一个例子，我写出了比较详细的注释。希望足够清晰。这个例子说明了，回调函数可以把调用者和被调用者分开，对于调用者来说，只需要知道自己要调用一个函数，该函数有一个string类型的参数，至于具体调用哪个，被调用的函数到底怎么执行，怎么解释该参数，是完全不用关心的。&lt;/p&gt;
&lt;pre lang=&#34;c&#34;&gt;
#include &lt;iostream&gt;  
#include &lt;string&gt;  
using namespace std;  

typedef void (*PF)(string s);  //定义一个名为PF的函数指针，该指针指向一类函数，该类函数有一个string类型的参数，返回值为void。  

void funcOne(string s)  //回调函数1  
{  
    cout &lt;&lt; s+&#34; One&#34;&lt;&lt; endl;  
}  

void funcTwo(string s)  //回调函数2 
{  
    cout &lt;&lt; s+&#34; Two&#34;&lt;&lt; endl;  
}  

void caller( PF pf, string s) //调用函数  
{  
    cout &lt;&lt; &#34;I am Caller Function&#34; &lt;&lt; endl;  
    pf(s);  
}  

int main()  
{  
    string str = &#34;Test CallBack Function&#34;;  
    PF pf1 = funcOne;  //实例化一个函数指针，指向func函数      
    caller(pf1, str);  
    pf1=funcTwo; 
    caller(pf1, str);  
    system(&#34;pause&#34;);  
    return 0;  
}  

&lt;/pre&gt;
&lt;p&gt;　　回调函数的一个很实用的例子就是泛型算法中的max算法，具体可以参见本文末尾的第一篇参考文档，
如果你在自行写代码中发生了
error C2679: 二进制“&amp;laquo;”: 没有找到接受“std::string”类型的右操作数的运算符(或没有可接受的转换)错误
　　说明你没有把string头文件导入，导入即可
　　个人能力有限，错误之处请留言指正，不胜感激。
参考：
&lt;a href=&#34;http://learn.akae.cn/media/ch24s05.html&#34;&gt;http://learn.akae.cn/media/ch24s05.html&lt;/a&gt;
&lt;a href=&#34;http://baike.baidu.com/view/414773.htm&#34;&gt;http://baike.baidu.com/view/414773.htm&lt;/a&gt;&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
