GPS,我徒步,你记录

GPS,我徒步,你记录说起徒步,似乎是个时髦的名词,其实,古已有之。我第一次远距离徒步,是大约四五步的时候。父母都上班了,把我和我哥留家里。
我哥逗我--当然我当时并不认为是逗我,类似于现在很多年轻人对很多事情很认
真一样--我哥逗我,敢不敢到跳窗户到后院去,这有何不敢;然后是敢不敢跳栅
栏,我们叫障子,到邻居家,这有何不敢;然后是敢不敢再跳出去,到家外面的
小路上,这有何不敢。然后我哥怕了,叫我回来,我不回去,开始徒步。穿过了半个通化市,到了市中
心。后来问过我哥,你咋不追我呢?答曰:我妈不让我出去啊。当时没有GPS,我这就算是走丢了。好在知道父母的姓名、工作单位,家住南山
委二委二组。警察叔叔给我爸的单位打了电话。故事其实比上面要复杂一些。其实我不是被警察叔叔的这个电话找到的, 而是
邻居丁大娘掐指一算,我在啥啥方位附近。该时,我正交通岗里吃萍果。这是第一次直接的经验,寻址能力是多么地重要。不管用啥方法寻得的。这也是另一次有意义的经验,GPS非常重要。后来就喜欢上了徒步。当时这种行为还未见报端,我私下称之为暴走。在城市当
中穿行,几公里时速,走上几个小时。从有了GOOGLE EARTH,我有时在地图上记录行走的轨迹,贴博客上。每次在地图
上丈量也挺费劲。前两天,典同学问到我那地图是怎么画的。当时是ditu.google.com截图,在上面
用GIMP画的。程同学就说:我这有更好的办法,GPS自动记录。GOOGLE纵横。以前也用过一下,但是除了典同学,居然没啥人一起用,就放弃了。听程同学推
荐,乐颠颠上去一看,满页都是 不能显示地图。没有这个级别的。后来程同学发来图,告诉我,这是一个叫做墙的万恶的家伙给挡住了。不能用。
翻墙即可。想我大好公民,以下省去文字若干。话说maps.google.comditu.google.com就有点不同。据说,为了国家安全,我国除了特种部门是不能绘制和出版地图的,虽说美帝国
主义都已经有那么清晰的卫星图了。这是技术问题,俺们不懂,类似于云南白药
对内是保密的,对美国啥啥部门仍至于公众,就公开了。不过,这些都是合理的。
只是道理不为我等外人所知也。由于地图要保密,GPS当然也是的。所以,凡在我国购买的GPS,上面都有一个纠
编的算法,就是说,测得的经纬度是经过修正的,这样才和地图上一致。而水货
的GPS,是没有修正的,所以测得的经纬度是准确的,但是在地图上一看,你明
明站在人民广场,地图上标的位置就可能跑到了伊通河里。我手机手机是标准的中国货。摩托罗拉Q11,长得很像黑莓。而且不是水货,所
以GPS是准的。准的的意思就是,被修正过的。买手机的时候,营业员特意告诉我:这手机好啊,GPS是免费的。我非常困惑,GPS还能收费么?这东西也不走流量,单向下行数据。这个故事告诉我们,部分事实是一种欺骗的手段。原因之一是当你知道全部事实
的时候会发现事实与他想让你知道的有所不同。而康德还是谁说了,道德,必须
考虑动机。根据以上,营业员是坏的。不过,是时,我已经成熟到即使别人忽悠我了,我也仍然接受他的正确一面,于
是,才有机会在后来又知道,他之所以推荐这一款,是因为这一款的利润高,而
不是适合于我。不过,以上并不改变GPS数据是经过修正这一事实。提醒你,GPS被修正过是好
事,合理的。根据墙的存在,谷歌纵横没法用了。于是程同学又推荐了一款软件,gpscam,拍
照片的时候能把GPS信息存在里面,也能记录。不幸,我的手机很有个性,没有找到相应的版本。又找。RaceChrono。这是一款芬兰人出的软件,野外运动的时候记录用的。还能
结队啥的。现在安装,能用到5月份,可以下载新版本。他们还义愤地声
明,iphone上的同名软件与他们无关。我用了它的基本功能,记录位置。RaceChoro导出的GPS数据,在maps.google.com有效,但在ditu.google.com上有偏移。
过程是:
1.racechoro记录数据;
2.导出成kml;
3.maps.google.com, mymaps-> create new map-> import然后就看到我的地图了。然后就可以截图上传显摆了。以后徒步,就可以自动记录啦。恩,辅以手动。不过,如果徒步到了外国,就不能用这种准的GPS啦。因为听说有些对安全不太
关注的国家,他们的GPS是没有经过修正的。注:GPS经过修正一事,最初是由典同学告诉我的。他买了一个带有未经过修正
的GPS的手机。iphone。替他显摆完毕。

打印1000,用函数指针数组作为递归的跳出条件

打印1000,用函数指针数组作为递归的跳出条件#include <stdlib.h>#include <stdio.h>void go(void){;}void quit(void){exit(0);}void (*where_to_go[2])(void)={go, quit};void calc(int current, int end){where_to_go[(current-1)/end]();// printf("%dt%dt%dn", current, end, current/end);printf("%dt",current);calc(++current, end);}main(){calc(1, 1000);printf("n");}

一个变态C/C++面试题的变态解法(要码农背景) zz

一个变态C/C++面试题的变态解法(要码农背景) zz发信人: SHENOK (陷入经济危机的牙), 信区: Joke
标 题: 一个变态C/C++面试题的变态解法(要码农背景)
发信站: 水木社区 (Tue Jan 11 23:14:22 2011), 站内
题目: 屏幕上打印1-1000这1000个数, 不许使用循环语句/条件语句,不许使用?:算符。
不许在源代码中用列举输出语句的办法傻打,比如一千个printf语句不行, 一个cout后面跟上1-1000这样的也不行,
不再赘述其他傻打行为, 大家都能领会精神。结果,出了好多千奇百怪的答案, 下面举一个例子void myprint(int n)
{
printf("%dn",n);
int t=1/(n-1000);
myprint(n+1);
}void main()
{
myprint(1);
}--
不明真相的群众的眼睛是雪亮的
※ 来源:·水木社区 newsmth.net·[FROM: 143.117.68.*]

Buffer是万恶之源

Buffer是万恶之源
断言啥玩意是万恶之源,是需要证据的,不能凭空诬陷。
甚至,我跳出来激动地说"我最近每天就睡两个小时,昼夜颠倒,白天还总被人
打电话吵醒。我这么不容易,怎么能是凭空诬陷呢。另外,我像这样的人吗。"
这也不行。需要证据。
事情是这样的。
Buffer者也,中文译名是 缓冲区,计算机术语。不过,下面要谈的,其实也不
怎么涉及计算机,看官不妨当此段作赋比兴之类。
起初,俺们是要整个程序。这程序分成两部分。一部分刘同学开发,负责从硬件
里把数据读出来,加加减减什么的,这部分不妨称 数据控;另一部分是关同学
开发,负责从 数据据 里把数据读出来,显示在人类容易看到的屏幕上面,画个
曲线啊什么的,这部分不妨称为 显摆控。
数据控是控数据的,显摆控是控显摆的,这样比较容易记了。于是事情就这样成
了。
数据控用C语言的风格写的C++,大致意思是风格古老而严谨。赞一下刘同学的程
序架构。
显摆控是用C#语言写的,大致意思是风格很in,效果很High。
这两部分如何交流呢。我们找了个特古老的技术,叫做管道。
数据据有了数据,交给管道;显摆控从管道里读了数据,即时的显摆出来。于
是,用设备的人看到了设备的数据。如果这样,事情就成了。
差啥呢?
发现1 数据不是一个一个出来的,而是一团子一团子出来的。或者如毛同学说
的,是一坨一坨出来的。本来电机走着,激光亮着,显摆的数据应该是电机走几
步,显摆一下,走几步,显摆一下,走几步,显摆一下...就像许多软件,非要
不停地告诉你"我干活呐,我正常工作呐,我可真干了不少啊。"
为了加强用户的安全感,和软件开发商的安全感,也许这是必要的。反正,俺们
准备要这个效果。
结果不是的。数据,一坨一坨出来的。
连这,也是好不容易发现的。最初看到的是,前面的一种数据,根本就不显摆,
后面的另一种数据,正常频率显摆。
明眼人一看便知:那一定是后面的数据与前面的数据是不同的技术手段。国情不
同,用同样的制度,所以结果也不一样。如同美英用资本主义就强大,日本也是
啊,而一些蕞尔小国用了,那就完犊子了。
但是! 这两部分都是刘同学一个人用同一种风格开发的,且风格严谨。严谨到啥
程度呢,关同学和俺用了两个来小时,想证明其中一行是错误的。最后,证明关
同学和俺试图证明那是错误的这一行为,是错误的。
后来! 关同学终于发现,前一种数据和后一种数据的速度不一样。再之前,关
同学还发现,前一种数据不是一点也不实时显摆,而是,一直不吭声,然后"哗
"一下,一堆数据出来了,中间过程就全没啥。
意思可能是,中间的过程你不用了解啦,反正有结果就行呗。
插话,好多同学喜欢这么干,这并非优良习惯。交互始终都是必要的。说了一百
遍了,不赘述。插话完毕。
是刘同学的程序有问题,是关同学的程序有问题?反正沟通中的问题,应该是其
中至少一方,或者双方的。
以下诊断的次序不分先后。
1 关同学换了刘同学的数据控程序,用来沟通,按相同的思路写了一个一样的,除了刘
同学的数据控读真正的设备,关同学的程序不读真正的设备,数据全是假的,但
是跟真的一样好。
观察的结果是: 用刘同学的数据控,数据就一团团;用关同学的伪数据控,数
据就很实时。
2 关同学换了关同学的程序显摆控,用来和刘同学的数据控沟通,按相同思路写
了一个一个的,除了真的显摆控逻辑更复杂一些,伪显摆控咔擦掉了一部分。
观察的结果是: 与用真显摆控没啥区别。
2.5 俺们用了一个传统的,微软公司开发的工具和刘同学的数据控沟通。换句话
说,权威出场啦。
观察结果:数据控快乐地工作着,一步一个脚印一声叫唤,实时得很。
从2和2.5分析,是不是看起来刘同学的数据控程序认人唯亲,不是领导不给好脸色啊。
可是从1分析, 是不是关同学的显摆控程序认人唯亲,不是自己家的产品就不好
好合作啊。
其实,不是的,这一切都只是假象。
因为刘的数据控和关的显摆控 根 本 从 来 就没有真正地直接地沟通过。
在两者之间,有一个叫做管道的东西存在。它声称自己接收的和发出的是完全相
同的。取之于啥用之于啥。但是,它并非如所声称的那样工作,或者说,在哪个
犄角九日日九,还有个别的文档,你也早就被表示过认同的,上面写着:
我告诉你的,才是真的;我不知道你的,就是不存在的。
不禁又冒着冷汗想起那段:
引文大意开始
问:哥是不是真实的一个人,还是只是一个虚幻的假的偶像?
答:你说的真实是啥意思?
问:就是像我这样存在的。
答:你不存在。
引文大意结束
因为刘的数据控和关的显摆控 根 本 从 来 就没有真正地直接地沟通过。
在他们之间,Buffer是万恶之源。
当刘的数据控与微软的那位领导(大名曰控制台)沟通的时候,buffer的长度是
0。即,管道知无不言,言无不尽,毫无保留,而时刻都没有保留。
当刘的数据控与关的显摆控合作的时候,buffer的长度被设置为天知道的一个长
度(注:"If the size of the internal buffer was unspecified when the
stream was constructed, its default size is 4 kilobytes (4096
bytes)."),反正不是0。那意思就是,"有数据,是啊,我有数据啦,但是我觉
得,怎么说捏,你现在还太幼稚,不适合都显摆出来。你还真的都想显摆出来
啊,那么,我只好不给你啦。这可是为了你好喔。"
我甚至不让你知道数据的存在。"真的没有数据,不信你读。GetLine(),果然啥
也没有吧。到一个阶段,我会把数据给你滴。什么,你想实时显摆,不是说了这
都是为你好么。"
Buffer对刘的数据控说,你给我的数据我接收到了,再来再来;Buffer对关的显
摆控说,还没有数据哩,你在等等。
最终,当数据大批涌向关的显摆控的时候,Buffer确实可以说,你看,我毫无保
留。
但是,你真的觉得这毫无不同么?
在工程中,我们不得不经常地 间接,而不是直接 使用材料和操作物件。
我们使用指针间接地访问变量; 我们使用文件封装了键盘和显示器; 我们使用
工具隔离高热和危险。
但是,我们从来没有说过, 当我们想利用工具的时候,工具可以剥夺我们直接触
摸世界的权利。
你可以劝我不要直视太阳,但是,请不要替我捂住眼睛。
所以,Buffer是万恶之源。
我还以为过了青春期就不用再这么叽歪了呐。

工作效率最高的地方 zz

工作效率最高的地方 zz想像一下一个典型的办公室,在一个银晃晃的大楼里,睡眼惺松地坐电梯上某一层,刷员工卡进到宽敞但被分为很多狭小隔间的办公室,每个隔间都塞满了电脑、文件夹等办公工具,明亮的灯光倒是赶走了不少睡意。可问题是,你在那儿工作效率高吗?
  37signals的创始人之一、《工作大解放(rework)》的作者Jason
Fried在TEDxMidwest上的观点就是,办公室很不幸已成为工作禁区,很多人在办公室办公的效率极低!他调查了很多人,问他们何时效率最高。答案各式各样,有特别喜好某一特定地点的,如:自家走廊、地下室、厨房、咖啡店、飞机、出租车、图书馆;也有特别钟爱某个时间段的,如黄昏、清晨、午夜……不过,这些答案中竟然没有"办公室"!?  为什么?Jason表示,办公室成了消磨时间的凶手,成了琐碎小事的集聚地。想想看,来办公室的路上花上1个小时;到了办公室整理文档、清理桌面、泡茶泡咖啡又可能消磨了半个小时;再吃个中饭,回来再跟同事聊聊八卦,又是一个小时;上司下午又召集大家开了个会,困得要死,不过幸好快下班了;五点了,收拾一下东西,看看今天的新闻。一天就结束了。很多时候办公室的工作只是流于形式,其中的时间折损是惊人的,1人消耗3小时,100人就变成了300个小时。时间就是金钱呀!效率就是生命呀!
  工作其实就像睡眠,它是有阶段顺序的,要进入深度睡眠状态,就得经过前面四个过程,并且中间不被打扰。所以工作,特别是那些需要思考与创意的工作,需要有一个持续漫长不被打扰的时间链。陈丹青也讲到,艺术学校不应该有"上课"与"下课",艺术是一个持续的过程,灵感来了就得全心全意地抓住它,实现从量变到质量的飞越,这时哪还顾得上什么休息?
  办公室是有各种各样的干扰因素,但公司担心员工若不在"办公室",怎么确保他们是在工作?他们上社交网站,看视频看碟怎么办?Jason说,拜托,社交网站时间就像是以前爹妈时代的咖啡时间了,总得让员工放松一下的嘛。况且这种是员工自身的因素,叫做"自愿干扰",办公室的干扰属于"强制干扰",管理层自己因为没有事情做,所以就专门组织开杀伤力特别大但一般又没有什么实际用途的会议。  那么究竟如何改变?如何让员工被问到工作效率最高的地方时,首先想起的就是办公室?
  Jason提出了几点建议:第一,安排某一天,比如星期四的下午是安静时间,任何人都不允许说话。这时候可以看到事情解决的进度明显加快;第二,改积极交流成消极交流,比如减少当面交流,更多地使用邮件。很多事情都不是重要紧急的,可以不打扰别人,尽管别,分清轻重缓急特别重要;第三,如果你是管理层,减少无聊会议的频率,如果你是员工,勇敢聪明地敲掉烦闷的会议吧,放心,很多会议是没有太大意义的。
  迎接新的工作模式,你,准备好了吗?

我所恐惧的

我所恐惧的罗素的<西方的智慧>,前几天看到莱布尼兹时代.这位就是与牛顿分别创造了微积
分的那位,他也是位哲学家,历史阴谋主义还认为他创造了类似达芬奇密码里的那
种兄弟会.其实似乎没有.不过,他的思想,比创造兄弟会还令人震撼得多.以前第一次从别的书上读到的时候,也没有多么注意;这次就觉得心有所感,又说不
清楚是什么,就把一段抄在了白板上.大意是: 整个世界的实体间是相互无关的, 事件之前也没有因果关系.你感觉到的因果关系,或者关系,是一种错觉. 打个比喻, 你的手表在走,我的手表
也在走,它们每秒钟都走一秒那么多,完全一致.这并非由于两只手表有任何机械的连接,而是因为它们属于同一个宇宙,受限于同
一种法则;或者说,由于他们是宇宙的一部分,所以表现出了全部宇宙的特征.后面说得就玄了.如果你了解了宇宙的法则--因为你也是宇宙的一部分,当然具
有这样的可能--你就理解了上帝.是不是会成为上帝,我忘了.我以为,我的心有所感就是以上这些.感觉沾沾自喜,想是不是能用这个编个故事唔
的.然后几天以后,我在凌晨刚刚睡下的时候,开始做梦.我很少做噩梦,即使做了噩梦也能在里面解决那些问题,即使解决不了,也能第一时
间醒过来.我知道,它们终归是假的,伤害不了我一分一毫.可是,这个梦里,我大声叫喊,愤怒而恐惧,却无法醒过来.甚至我醒过来的时候,也
没有意识到刚刚那是梦境.梦里, 整个世界是一块酥饼, 看似完整, 表面却满是龟裂, 随时都可以碎裂为很
多块, 彼此毫不相连.小时候,因为吃这类东西掉碴被批过,所以从此不喜欢.此刻,却不仅仅是喜欢与否,而
是盯着手上的东西,颤抖.如果这个世界的每个部分彼此永不相连...如果这个世界上,你做的每一件事都可以不计后果,...我们的未来, 我们, 还有什么希望.我拼命试图修复这个世界, 在梦里, 可笑地一次次把酥饼拼起来, 然后看它变得
更加破碎.碎末掉了一地.我大声号叫. 完全醒过来以后, 也许几天后的此刻, 才意识到, 真正的孤独是每
一个人都在人群之中,却彼此永不相见; 真正的绝望, 还不是没有未来, 而是你现
在所做的, 对未来没有一丝影响.未来一秒的,就是另一个你.而此刻的这一个你, 深情的, 害怕的, 哭泣的, 努力的, 从此消失, 永不再来.我才知道, 对于活在当下, 我不仅是厌恶,而是恐惧.如果我们是没有未来的原子,彼此孤立,还有什么努力和自由意识是有意义的.周遭的一切,转瞬即逝;彼此的关连,尽是虚幻;没有未来,没有义气.------------世界,不会是那样的.我们并非生活在这一刻, 而是生活在未来.只不过,是日,全身过敏. 只不过,12月21日冬至.

生熟关系与城乡差别 zz

生熟关系与城乡差别 zz
[http://www.gaozz.cn/blog/space.php?uid=68&do=blog&id=39725
]
传统的中国是个熟人社会,越在乡村,熟人的味道就越浓厚。熟人越多,一个人的社会活动范围也就越大。可以说,熟人圈实际上就是传统乡民社会的社交圈。在他们眼中,圈子里面的人总是比圈子外边的人来得自然和亲切。
相对而言,城市是一个由陌生人组成的文化空间。这个空间中的陌生人越多,一个人的熟人圈子就会越小。不过,由于一个人的活动空间总是相对稳定,这种相对固化的城市空间就为陌生人转化为熟人提供了温床。因此,城市并非完全的陌生人社会,而是一个生熟夹杂伴生的社会。共同的目的、利益、兴趣、爱好等等,都可以促成陌生社会向熟人社会的转变。只不过,城市空间越大,流动人口越多,陌生人就会越多,而个人的熟人社会却不一定会随着城市空间的扩张而拓展,而是相对稳定。这是由一个人的社会活动状况所决定的。
今天上午,我在自己居住的街区中的中国工商银行支行办理现金支票对公业务的过程中,亲身感受了这种生熟关系的影响。当时,等待办理业务的客户有五六十人,除了部分客户自己是VIP外,大多是一般的客户。取号排队等候办理本是常事,但该支行里有几位职员不时拿自己的银行卡刷卡取号给刚进来的客人,那些人似乎并不是银行职员的亲戚,而更像熟人。但是,银行职员给予他们熟人少排队先办业务的优惠或特权,却造成了先排队却久未轮到办理业务的社会不公。见微知著,城市中的熟人圈子一旦泛滥起来,它所造成的危害比传统乡村社会更大,也更可怕。原因很简单,城市人除了会考虑熟人圈子内的面子和感受之外,面对陌生人时已经不知道害臊了,也更麻木不仁了……

Emacs设置默认字体

Emacs设置默认字体有的时候戴框架眼镜,希望字体大些;
有的时候戴隐形眼镜,希望能同时看到更多东西.
默认字体,是Emacs每次启动时使用的字体.
希望在长久的将来,两种场景仍能有交集.方案2 中英文使用不同字体* 第1步 设置当前字体shift 鼠标左键,选择一个字体(字体,大小,字型).* 第2步 查看字体名M-x describe-fontset RET RET* 第3步 设置默认字体编辑.emacs文件,加入以下内容.
;------------------------------
(create-fontset-from-fontset-spec
"-outline-Consolas-normal-r-normal-normal-16-120-96-96-c-*-iso8859-1,
ascii:-outline-Consolas-normal-r-normal-normal-16-120-96-96-c-*-iso8859-1,
chinese-gbk:-outline-宋体_方正超大字符集-normal-r-normal-normal-16-120-96-96-c-*-gb2312*-*,
chinese-gb2312:-outline-宋体_方正超大字符集-normal-r-normal-normal-16-120-96-96-c-*-gb2312*-*")(set-default-font
"-outline-Consolas-normal-r-normal-normal-16-120-96-96-c-*-iso8859-1")
;------------------------------
详情参见 create-fontset-from-fontset-spec 和
[http://www.gnu.org/software/emacs/manual/html_node/emacs/Defining-Fontsets.html].
方案1 英文字体* 第1步 设置当前字体shift 鼠标左键,选择一个字体(字体,大小,字型).* 第2步 查看字体名M-x describe-font RET RET* 第3步 设置默认字体
编辑.emacs文件,加入以下内容.;------------------------------
(set-default-font
"-outline-Consolas-normal-r-normal-normal-16-120-96-96-c-*-iso8859-1")
;------------------------------其中类似
"-outline-Consolas-normal-r-normal-normal-16-120-96-96-c-*-iso8859-1"的
,就是第2步中看到的字体名.每一行,冒号以前的,是字符集,冒号以后的,是上述字体名.
以上,在 windows mingw32下通过.

Fwd: 神秘常量复出!用0x077CB531计算末尾0的个数

 
 

Sent to you by Young via Google Reader:

 
 

via Matrix67: My Blog on 12/15/10

    大家或许还记得 Quake III 里面的一段有如天书般的代码,其中用到的神秘常量 0x5F3759DF 究竟是怎么一回事,着实让不少人伤透了脑筋。今天,我见到了一段同样诡异的代码。
    下面这个位运算小技巧可以迅速给出一个数的二进制表达中末尾有多少个 0 。比如, 123 456 的二进制表达是 1 11100010 01000000 ,因此这个程序给出的结果就是 6 。 unsigned int v;  // find the number of trailing zeros in 32-bit v
int r;           // result goes here
static const int MultiplyDeBruijnBitPosition[32] =
{
  0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
  31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
r = MultiplyDeBruijnBitPosition[((uint32_t)((v & -v) * 0x077CB531U)) >> 27];     熟悉位运算的朋友们可以认出, v & -v 的作用就是取出右起连续的 0 以及首次出现的 1 。当 v = 123 456 时, v & -v 就等于 64 ,即二进制的 1000000 。怪就怪在,这个 0x077CB531 是怎么回事?数组 MultiplyDeBruijnBitPosition 又是什么玩意儿呢?
    这还得从 0x077CB531 本身的一个性质开始说起。把这个常数写成 32 位二进制,可以得到 00000111011111001011010100110001     这个 01 串有一个无比牛 B 的地方:如果把它看作是循环的,它正好包含了全部 32 种可能的 5 位 01 串,既无重复,又无遗漏!其实,这样的 01 串并不稀奇,因为构造这样的 01 串完全等价于寻找一个有向图中的 Euler 回路。如下图,构造一个包含 16 个顶点的图,顶点分别命名为 0000, 0001, 0010, …, 1111 。如果某个点的后 3 位,正好等于另一个点的前 3 位,就画一条从前者出发指向后者的箭头。也就是说,只要两个顶点上的数满足 abcd 和 bcde 的关系( a 、 b 、 c 、 d 、 e 可能代表相同的数字),就从 abcd 出发,连一条到 bcde 的路,这条路就记作 abcde 。注意,有些点之间是可以相互到达的(比如 1010 和 0101 ),有些点甚至有一条到达自己的路(比如 0000 )。        构造一个字符串使其包含所有可能的 5 位 01 子串,其实就相当于沿着箭头在上图中游走的过程。不妨假设字符串以 0000 开头。如果下一个数字是 1 ,那么 00001 这个子串就被包含了,同时最新的 4 位数就变成了 0001 ;但若下一个数字还是 0 ,那么 00000 就被包含了进来,最新的 4 个数仍然是 0000 。从图上看,这无非是一个从 0000 点出发走了哪条路的问题:你是选择了沿 00001 这条路走到了 0001 这个点,还是沿着 00000 这条路走回了 0000 这个点。同理,每添加一个数字,就相当于沿着某条路走到了一个新的点,路上所写的 5 位数就是刚被考虑到的 5 位数。我们的目的便是既无重复又无遗漏地遍历所有的路。显然图中的每个顶点入度和出度都是 2 ,因此这个图一定存在 Euler 回路,我们便能轻易构造出一个满足要求的 01 串了。这样的 01 串就叫做 De Bruijn 序列。     De Bruijn 序列在这里究竟有什么用呢?它的用途其实很简单,就是为 32 种不同的情况提供了一个唯一索引。比方说, 1000000 后面有 6 个 0 ,将 1000000 乘以 0x077CB531 ,就得到    00000111011111001011010100110001
-> 11011111001011010100110001000000     相当于把 De Bruijn 序列左移了 6 位。再把这个数右移 27 位,就相当于提取出了这个数的头 5 位:    11011111001011010100110001000000
->                            11011     由于 De Bruijn 序列的性质,因此当输入数字的末尾 0 个数不同时,最后得到的这个 5 位数也不同。而数组 MultiplyDeBruijnBitPosition 则相当于一个字典的功能。 11011 转回十进制是 27 ,于是我们查一查 MultiplyDeBruijnBitPosition[27] ,程序即返回 6 。
    注意到当输入数字的末尾 0 个数超过 27 个时,程序也是正确的,因为左移时低位正好是用 0 填充的。     这段神一般的代码取自 http://graphics.stanford.edu/~seander/bithacks.html ,欢迎大家前去围观。

 
 

Things you can do from here: