以文本方式查看主题

-  计算机科学论坛  (http://bbs.xml.org.cn/index.asp)
--  『 编程心得 』   (http://bbs.xml.org.cn/list.asp?boardid=42)
----  (第四期获奖名单公布,最新4节的电子版pdf已开放下载) [B][RED] 预览电子版,写书评,赢取《编程之美—微软技术面试心得》(微软亚洲研究院邹欣等主编),每周送出3本,机会多多![/RED][/B],欢迎参加由博文视点和本站联合举办的有奖征集书评活动  (http://bbs.xml.org.cn/dispbbs.asp?boardid=42&rootid=&id=61162)


--  作者:admin
--  发布时间:4/10/2008 5:10:00 PM

--  (第四期获奖名单公布,最新4节的电子版pdf已开放下载) [B][RED] 预览电子版,写书评,赢取《编程之美—微软技术面试心得》(微软亚洲研究院邹欣等主编),每周送出3本,机会多多![/RED][/B],欢迎参加由博文视点和本站联合举办的有奖征集书评活动

=========================================================
               获 奖 名 单
=========================================================

第一期:zellux,jpz6311whu,Humphrey
第二期:NullDream,conan_holmes,jason_00
第三期:卷积内核,蝶影,tomcatwilson
第四期:xjs1231,DMman,冬天的农夫


=========================================================
               本 次 活 动 介 绍
=========================================================

参与办法  

下载本站独家样章 --->  阅读样章 --->  回复本贴,提交 书评 --->  每周抽奖

第一期 (内含:求二进制数中1的个数,计算字符串的相似度,求二叉树中节点的最大距离,金刚坐飞机问题) :
点击下载

第二期 (内含:中国象棋将帅问题,饮料供货,不要被阶乘吓倒,寻找发帖“水王”):

第三期:(内含:连连看游戏设计,1的数目,寻找最大的K个数,精确表达浮点数)

第四期:(内含:子数组的最大乘积,计算字符串的相似度,瓷砖覆盖地板,编程判断两个链表是否相交)

活动时间    
2008年4月11日——2008年5月9日

活动规则
1)本站每周提供书中的4节样章(电子工业出版社授权本站提供的独家样章),供大家阅览,并撰写书评。
2)每位读者可以发表多条书评。
3)本站和博文视点将在每周抽取3名幸运获奖者。
4)书评字数不限,简短精悍、详细全面均可。
5)请直接在此回帖发表书评。

活动奖品
本次活动每周将产生3名获奖者,奖品是《编程之美——微软技术面试心得》图书一本。


感谢电子工业出版社博文视点赞助本次活动!
更多好书、新书信息,敬请关注博文视点官方博客:http://blog.csdn.net/bvbook


按此在新窗口浏览图片  按此在新窗口浏览图片


=========================================================
               本 书 详 情
=========================================================


按此在新窗口浏览图片



IT企业面试真题
CSDN总编 孟岩、资深技术作家 潘爱民 推荐
微软全球副总裁 沈向阳 倾情作序
连续两周互动出版网(China-pub)计算机类销售冠军!


书名:《编程之美——微软技术面试心得》
作者:邹欣等
书号: 978-7-121-06074-8
出版社:电子工业出版社
出版日期:2008年3月
定价:40元
开本:16开
版次:1-1
页码:384页
本书详细信息:http://www.china-pub.com/38070


作者介绍

邹欣,现任微软亚洲研究院技术创新组研发主管。他从1996年起在微软Outlook 产品团队从事开发工作, 2003 年到2005 年,在微软Visual Studio Team System产品团队负责软件质量管理工具的开发。加入微软前,邹欣从事过商用Unix 系统、GPS/GIS 软件开发以及软件测试工作。2007年出版了《移山之道—— VSTS软件开发指南》一书。他1991 年获北京大学计算机软件专业学士学位。1996 年获美国Wayne State University (韦恩州立大学) 计算机软件专业硕士学位


推荐

◆ 微软公司全球资深副总裁沈向洋 推荐序
http://www.amazon.cn/mn/detailApp?prodid=bkbk821857

◆ 这是一本让人着迷的书! 孟岩评《编程之美——微软技术面试心得》
http://www.china-pub.com/member/bookbar/bookreview.asp?theid=291

◆ 潘爱民倾力推荐《编程之美——微软技术面试心得》
http://blog.csdn.net/panaimin/archive/2008/02/12/2089151.aspx

◆ CSDN读者薛笛:
《编程之美》读书笔记(一):中国象棋将帅问题
http://blog.csdn.net/bvbook/archive/2008/04/09/2269918.aspx
《编程之美》读书笔记(二): 一摞烙饼的排序问题
http://blog.csdn.net/bvbook/archive/2008/04/10/2277818.aspx

◆ 新浪作者《编程之美》和《无以言退》
http://blog.csdn.net/bvbook/archive/2008/04/04/2248838.aspx


读者评价

● “买了这本书,已经看了三个例题,打算每个晚上看一个实例
平时看<算法导论>总感觉是那么的苦涩,那么的深奥.有些还看了真是难懂.
不过这本书表面上是讲解算法,但更体现一种面对困难,解决问题的心态.
个人还是挺喜欢这类的书,把编程人性化了。”    ——  china-pub读者 拓荒者

● “初看本书书名,一阵恶心,扯到微软面试心得上面可能是出于出版社对销售上面的考虑,个人认为光看这么一本书,并不能帮助你进入微软,要想进入微软,需要的是你的独立思考能力,而这本书更大的作用是在于此,给你一个有趣的题,让你自己去思考,思考出来后再对照他给出的解法答案对比你是否作对,而在这个过程中,你学会了作为一个程序员最重要的东西,独立思考的能力。而不是到网上到处找代码片段,解决方案,Copy/Paste。书已经买了,但是还没有到,我打算到了以后好好的阅读一下本书,看看是否值得这个价钱。”    ——  china-pub读者 CoolJie2001 

● “相当启发人的书。之前从没有想过枯燥的算法可以这么好玩。展开的讨论十分深入细致。值得认真看每一个问题:)当然也有一些缺点,比如尽管有了勘误,但还是有许多细小的错误。比如前后文不一致(貌似不是一个人写的),代码变量使用错误之类的。但如果认真研究了,就能很轻易的找到~。
有些问题避开了一些关键的难点,比如那个n条直线可以将平面空间划分为多少块区域的题,完全避开了如何表示直线和如何计算之间交点的过程。
余下的等看完再写:)”    ——  china-pub读者 speedfirst 

● “虽然没有看完此书,但忍不住说两句。
首先,这本书无疑是严谨的,可以想见付出了巨大的努力。
其次,截至目前看到的内容都很有启发性,令人难忘。
如果一定要挑出一些问题,主要存在这样一些不足
(1)问题描述部分有些弱,应该把问题解释清楚,有些问题的描述并不那么清楚,可以举一些简单的例子来表述,让读者首先了解问题。
(2)展开的部分很好,无懈可击,堪称完美,但有些地方可以增加一些参考文献的引用,帮助更好的理解,另外可以多一些图形化的方法来解释复杂的问题,否则有些地方看起来比较吃力。
(3)代码的部分也很精彩,有些细微的格式有些问题,代码风格很统一,代码刻录成光盘可能更好,这样会占一些书籍篇幅,而且排版的难度会很大。综上,此书堪称IT行业图书的上上之美,不虚此名。”    ——  china-pub读者 cathymm 

● “在微软拿到了一本有各位作者签名的程序之美,感觉还不错,虽然不少问题都是经典的题型了,不过能汇总起来很不简单了,而且从行文的方式上来看适合轻松消遣的书,建议买来看看。    ”    ——  china-pub读者 coolzzz 

● “看完此书才发现自己在编程领域还很嫩啊,编程,我才刚上路呢.”    ——  china-pub读者 lzp22 

(期待您的评价)

[此贴子已经被作者于2008-5-12 11:25:30编辑过]

--  作者:mfc42d
--  发布时间:4/10/2008 8:00:00 PM

--  
支持一下,考自己的基本功
--  作者:wangxiaomi
--  发布时间:4/10/2008 8:13:00 PM

--  
踊跃参加
--  作者:卷积内核
--  发布时间:4/11/2008 8:26:00 AM

--  
看了上面的书评有点向往这本经典著作了。
--  作者:Jason.F
--  发布时间:4/11/2008 11:42:00 AM

--  
你是不是符合型人才?你敢来这里挑战吗?这里给你答案!
--  作者:Jason.F
--  发布时间:4/11/2008 5:56:00 PM

--  
版主的題目已出,各位學生請接旨!

状元、榜眼、探花、进士 每週將公佈!

請各位學生,密切關注!


--  作者:Jason.F
--  发布时间:4/11/2008 5:58:00 PM

--  
要認真作答!不得抄襲,偷看呦!
--  作者:iihero
--  发布时间:4/12/2008 12:13:00 AM

--  
看了一下样章,确实深受启发,一个简单的问题,为了追求效率,竟然有N多种解决方案,而这些方案中只能有一种是最合适的。
因而,这本书给我更大的启发就是,算法也是因实际情况而定的,合适的数据结构,配合一定的算法,真的应该是软件系统的灵魂。

期待这本书的早日出版。


--  作者:hjx_221
--  发布时间:4/12/2008 8:04:00 AM

--  
期待这本书的早日出版。

--  作者:admin
--  发布时间:4/12/2008 10:46:00 AM

--  
这本书,已经出版了。
--  作者:wangxiaomi
--  发布时间:4/12/2008 12:48:00 PM

--  
《编程之美》2008年3月底已经上市了。
--  作者:阳光小虾
--  发布时间:4/12/2008 9:30:00 PM

--  
看了1章,讲计算字符串相识问题的。内容对我来说有点难(因为我还没认真学习过编程算法),我读了一章,感觉作者写书思路很好,先列举问题,然后写思考步骤,然后给出参考code,最后再引申一下,让读者自己去思考。在国内案例教学书本满天飞的时候,能这样唤醒读书人从另一个角度去思考问题,而且好像还在培养我们解决问题的一种方式。(至少目前指导我的前辈是这么教我的,我想有不少编程的人可能和我一样,拿到问题可能总是急于code(我就有这个毛病),然后遇到问题gg一下,baidu一下,再不行,就很"心安理得"的去发问了。最后就算解决了,对问题本身的思考是不够的,这样也许是一个解决问题的恶性循环。)

不过这本书的的定位我还不太清楚(也许是我读得太快太少的原因 ^_^),是想通过它唤醒编程人员对算法的重视呢?还是想展示一下编程的魅力?还是想带一般的编程人员进入更高的境界?还是想。。。

如果是象前面的朋友说的,是想以一种诙谐幽默而不失严谨的方式带读者去游览一番算法的领域,那么我个人觉得还不够浅显哦。象我学设计模式,就读了一本我觉得很不错的书。《Head.First设计模式》,这个作者讲解得很浅显,易懂。至少把不少人说得死难的问题,让一般的读者都可以读懂。而我读算法这个第一章,好像没读懂,大脑还是有点混乱。也许是我接触得少的愿意。

最后还是要感谢一下作者,出了一本不错的书给我们品味。也许它就如那苦丁茶,要慢慢品味,才可以品出它的味儿来。


--  作者:Spark
--  发布时间:4/13/2008 1:04:00 PM

--  
大致看了一下,本书对问题的描述方式很有趣,解题的思路也很明确。
--  作者:sswv
--  发布时间:4/13/2008 11:10:00 PM

--  
我第一次听说《编程之美——微软技术面试心得》,是在博客堂2007年会上。当时和邹欣先生坐得不远,他简要地介绍了《编程之美》的内容和写作进度。不久前我在电子科技书店看到此书已经上架,于是借来一阅。
  此书的优点无须我多言。算法是计算机程序设计的灵魂,是每个计算机专业学生和从业人员必须具备的基础素质之一。微软把一些看似简单,但蕴含深刻内涵的算法题目作为面试的重要内容,是经过深思熟虑的。
  不过从我个人角度出发,我更希望看到一本讲述与计算机体系结构、操作系统等原理相关的“经典问题”、“面试心得”一类的书籍。就如同《编程之美》第1.1节的内容,从计算机软硬件实现的角度出发,引出问题,进而提出算法。与从数学问题直接引出算法相比,更贴近研发人员的实际。
  例如竞态条件和死锁、流水线分析和设计等问题,在计算机专业课本中都是生硬的理论和千篇一律的例子。提到读者写者,我们马上就会想到竞态、并发、死锁等问题,但在一个现实的程序或项目中,缺乏经验的编程人员往往不会立刻发现自己遇到的情形恰恰可以套用读者写者模型。从现实程序问题到算法数学原理,需要体系结构模型的过渡。
  算法和工程是分别是研究和开发人员必备的基本能力,我觉得我的这点期望是二者的交融点。

--  作者:卷积内核
--  发布时间:4/14/2008 8:18:00 AM

--  
    关于《编程之美——微软技术面试心得》之前就看到网站上包括微软公司全球资深副总裁沈向洋和编程界无人不知的潘爱民等很多高手的推荐,看这些评价之后对该书就有非常向往之感了。
    很荣幸在中国XML论坛看到了该书的样章,提前拜读了其中的很多章节,就《求二进制数中1的个数》这一节来说,我想所有程序员应该都写过类似的代码。以前我用到的时候使用其中的解法二:使用位操作,因为现在写程序只要不是太离普就很少考虑复杂度问题。当看到解法三的时候就感觉为之一振,自问还有这种简洁明了思路怎么就没考虑到呢?怀着激动的心情继续往下看,一直到解法五将时间复杂度降到O(1),那种山外有山人外有人的体会就更加刻骨铭心了。
    我认为该书并不仅是参加面试人员必读的,更广来说从事写程序的人更要字斟句酌的仔细研读,它里面包含了很多技术和思想都是我们必须具备的东西。希望更多的人能读到该书,从中体会并学习到更多的思想、技术和经验。


--  作者:jpz6311whu
--  发布时间:4/14/2008 11:06:00 AM

--  
从本书的样章内容不难看出,本书通过实际问题例子讲解编程的技巧和艺术。例子都是通过作者精心选择的典型案例,很具代表性。每个例子后面不光是只是答案的描述,还有解题思路的引导,使读者在思考中获得启发,在启发中获得提高。而且往往同一个问题作者提出多种解题思路,并从效率等多个角度进行对比,使读者的思路进一步开阔起来。另外,每个问题之后,作者都会提出一个进一步的开放性问题留给读者思考和练习作为结束,对这个问题感兴趣的读者可以通过这个扩展问题进一步巩固对解题技巧的理解,而不会读了就忘了。

总之,读这本书的时候,不会感到枯燥,会感觉是在和一个经验丰富的编程老手讨论某些有趣的问题。


--  作者:drizzlecrj
--  发布时间:4/14/2008 12:12:00 PM

--  
算法精妙, 很好很强大!
--  作者:dahuaidan
--  发布时间:4/14/2008 7:27:00 PM

--  
金刚坐飞机的问题很有意思,呵呵
--  作者:zellux
--  发布时间:4/15/2008 12:29:00 AM

--  
这里我想针对样章上的一个问题谈谈自己的理解。

问题很简单,求二进制中1的个数。对于一个字节(8bit)的变量,求其二进制表示中"1"的个数,要求算法的执行效率尽可能的高。

先来看看样章上给出的几个算法:

解法一,每次除二,看是否为奇数,是的话就累计加一,最后这个结果就是二进制表示中1的个数。

解法二,同样用到一个循环,只是里面的操作用位移操作简化了。

   1:  int Count(int v)   
   2:  {   
   3:      int num = 0;
   4:      while (v) {   
   5:          num += v & 0x01;   
   6:          v >>= 1;   
   7:      }   
   8:      return num;   
   9:  }

解法三,用到一个巧妙的与操作,v & (v -1 )每次能消去二进制表示中最后一位1,利用这个技巧可以减少一定的循环次数。

解法四,查表法,因为只有数据8bit,直接建一张表,包含各个数中1的个数,然后查表就行。复杂度O(1)。

   1:  int countTable[256] = { 0, 1, 1, 2, 1, ..., 7, 7, 8 };   
   2:      
   3:  int Count(int v) {   
   4:      return countTable[v];   
   5:  }
   
好了,这就是样章上给出的四种方案,下面谈谈我的看法。

首先是对算法的衡量上,复杂度真的是唯一的标准吗?尤其对于这种数据规模给定,而且很小的情况下,复杂度其实是个比较次要的因素。

查表法的复杂度为O(1),我用解法一,循环八次固定,复杂度也是O(1)。至于数据规模变大,变成32位整型,那查表法自然也不合适了。

其次,我觉得既然是这样一个很小的操作,衡量的尺度也必然要小,CPU时钟周期可以作为一个参考。

解法一里有若干次整数加法,若干次整数除法(一般的编译器都能把它优化成位移),还有几个循环分支判断,几个奇偶性判断(这个比较耗时间,根据CSAPP上的数据,一般一个branch penalty得耗掉14个左右的cycle),加起来大概几十个cycle吧。

再看解法四,查表法看似一次地址计算就能解决,但实际上这里用到一个访存操作,而且第一次访存的时候很有可能那个数组不在cache里,这样一个cache miss导致的后果可能就是耗去几十甚至上百个cycle(因为要访问内存)。所以对于这种“小操作”,这个算法的性能其实是很差的。

这里我再推荐几个解决这个问题的算法,以32位无符号整型为例。

   1:  int Count(unsigned x) {   
   2:     x = x - ((x >> 1) & 0x55555555);    
   3:     x = (x & 0x33333333) + ((x >> 2) & 0x33333333);    
   4:     x = (x + (x >> 4)) & 0x0F0F0F0F;    
   5:     x = x + (x >> 8);    
   6:     x = x + (x >> 16);    
   7:     return x & 0x0000003F;    
   8:  }
   
这里用的是二分法,两两一组相加,之后四个四个一组相加,接着八个八个,最后就得到各位之和了。

还有一个更巧妙的HAKMEM算法

   1:  int Count(unsigned x) {
   2:     unsigned n;    
   3:      
   4:     n = (x >> 1) & 033333333333;    
   5:     x = x - n;   
   6:     n = (n >> 1) & 033333333333;   
   7:     x = x - n;    
   8:     x = (x + (x >> 3)) & 030707070707;   
   9:     x = modu(x, 63);  
   10:     return x;   
   11:  }
   
首先是将二进制各位三个一组,求出每组中1的个数,然后相邻两组归并,得到六个一组的1的个数,最后很巧妙的用除63取余得到了结果。

因为2^6 = 64,也就是说 x_0 + x_1 * 64 + x_2 * 64 * 64 = x_0 + x_1 + x_2 (mod 63),这里的等号表示同余。

这个程序只需要十条左右指令,而且不访存,速度很快。

由此可见,衡量一个算法实际效果不单要看复杂度,还要结合其他情况具体分析。

关于后面的两道扩展问题,问题一是问32位整型如何处理,这个上面已经讲了。

问题二是给定两个整数A和B,问A和B有多少位是不同的。

这个问题其实就是数1问题多了一个步骤,只要先算出A和B的异或结果,然后求这个值中1的个数就行了。

总体看来这本书还是很不错的,比较喜欢里面针对一个问题提出不同算法并不断改进的风格。这里提出一点个人的理解,望大家指正 ;-)


(by ZelluX   http://www.blogjava.net/zellux)



--  作者:卷积内核
--  发布时间:4/15/2008 8:14:00 AM

--  
以下是引用zellux在2008-4-15 0:29:00的发言:
这里我想针对样章上的一个问题谈谈自己的理解。

问题很简单,求二进制中1的个数。对于一个字节(8bit)的变量,求其二进制表示中"1"的个数,要求算法的执行效率尽可能的高。

先来看看样章上给出的几个算法:

解法一,每次除二,看是否为奇数,是的话就累计加一,最后这个结果就是二进制表示中1的个数。

解法二,同样用到一个循环,只是里面的操作用位移操作简化了。

    1:  int Count(int v)   
    2:  {   
    3:      int num = 0;
    4:      while (v) {   
    5:          num += v & 0x01;   
    6:          v >>= 1;   
    7:      }   
    8:      return num;   
    9:  }

解法三,用到一个巧妙的与操作,v & (v -1 )每次能消去二进制表示中最后一位1,利用这个技巧可以减少一定的循环次数。

解法四,查表法,因为只有数据8bit,直接建一张表,包含各个数中1的个数,然后查表就行。复杂度O(1)。

    1:  int countTable[256] = { 0, 1, 1, 2, 1, ..., 7, 7, 8 };   
    2:      
    3:  int Count(int v) {   
    4:      return countTable[v];   
    5:  }
    
好了,这就是样章上给出的四种方案,下面谈谈我的看法。

首先是对算法的衡量上,复杂度真的是唯一的标准吗?尤其对于这种数据规模给定,而且很小的情况下,复杂度其实是个比较次要的因素。

查表法的复杂度为O(1),我用解法一,循环八次固定,复杂度也是O(1)。至于数据规模变大,变成32位整型,那查表法自然也不合适了。

其次,我觉得既然是这样一个很小的操作,衡量的尺度也必然要小,CPU时钟周期可以作为一个参考。

解法一里有若干次整数加法,若干次整数除法(一般的编译器都能把它优化成位移),还有几个循环分支判断,几个奇偶性判断(这个比较耗时间,根据CSAPP上的数据,一般一个branch penalty得耗掉14个左右的cycle),加起来大概几十个cycle吧。

再看解法四,查表法看似一次地址计算就能解决,但实际上这里用到一个访存操作,而且第一次访存的时候很有可能那个数组不在cache里,这样一个cache miss导致的后果可能就是耗去几十甚至上百个cycle(因为要访问内存)。所以对于这种“小操作”,这个算法的性能其实是很差的。

这里我再推荐几个解决这个问题的算法,以32位无符号整型为例。

    1:  int Count(unsigned x) {   
    2:     x = x - ((x >> 1) & 0x55555555);    
    3:     x = (x & 0x33333333) + ((x >> 2) & 0x33333333);    
    4:     x = (x + (x >> 4)) & 0x0F0F0F0F;    
    5:     x = x + (x >> 8);    
    6:     x = x + (x >> 16);    
    7:     return x & 0x0000003F;    
    8:  }
    
这里用的是二分法,两两一组相加,之后四个四个一组相加,接着八个八个,最后就得到各位之和了。

还有一个更巧妙的HAKMEM算法

    1:  int Count(unsigned x) {
    2:     unsigned n;    
    3:      
    4:     n = (x >> 1) & 033333333333;    
    5:     x = x - n;   
    6:     n = (n >> 1) & 033333333333;   
    7:     x = x - n;    
    8:     x = (x + (x >> 3)) & 030707070707;   
    9:     x = modu(x, 63);  
    10:     return x;   
    11:  }
    
首先是将二进制各位三个一组,求出每组中1的个数,然后相邻两组归并,得到六个一组的1的个数,最后很巧妙的用除63取余得到了结果。

因为2^6 = 64,也就是说 x_0 + x_1 * 64 + x_2 * 64 * 64 = x_0 + x_1 + x_2 (mod 63),这里的等号表示同余。

这个程序只需要十条左右指令,而且不访存,速度很快。

由此可见,衡量一个算法实际效果不单要看复杂度,还要结合其他情况具体分析。

关于后面的两道扩展问题,问题一是问32位整型如何处理,这个上面已经讲了。

问题二是给定两个整数A和B,问A和B有多少位是不同的。

这个问题其实就是数1问题多了一个步骤,只要先算出A和B的异或结果,然后求这个值中1的个数就行了。

总体看来这本书还是很不错的,比较喜欢里面针对一个问题提出不同算法并不断改进的风格。这里提出一点个人的理解,望大家指正 ;-)


(by ZelluX   http://www.blogjava.net/zellux)




很好很强大,不过更像是读书笔记而不是书评。


--  作者:netjian
--  发布时间:4/15/2008 12:53:00 PM

--  
转自:编程之美中的实习生作者,陈远BLOG

很多人都说编程的人怀揣着一个改变世界的梦想,无数的年轻人投身其中,用梦想和思考改变世界。微软亚洲研究院的八名程序员和实习生集体创作出了一本“编程之美”,用文字和符号与同道人沟通共同的编程梦想,并把它献给微软亚洲研究院成立十周年。下面,让我们来听听其中一名实习生作者所理解的编程之美。

    我应该算是最早知道将要编写《编程之美-微软面试指南》这本书的少数几个人之一,那时邹欣老师正在对《移山之道》进行最后的润色,而我还在学校里上研究生课程,生平第一次接受正统的计算机专业教育。当邹老师问我要不要参与编写时,做为一名自诩的“文学青年”而不是“计算机高手”,我毫不犹豫地答应了。

         我本科读的是航空学院,在大二时闲得无聊抱着玩的心态才开始真正自学编程的,然后凭着热情和兴趣就一头扎了进来。但是,我心里一直有种隐隐的痛,我可以熟练使用ASP.NET、AJAX很快地做出一个网站来,却对一些基本的数据结构、算法一知半解。唯一一次认真去读《数据结构》那本书还是保研考试前一夜临时抱佛脚,通宵看了排序、树、图之类常考的重点。虽然最后考出来成绩不错,但自己斤两多少,自己最清楚。所以实际上我对许多公司偏重算法的面试一直以来都抱有一种畏惧感和神秘感,而且非常仰慕那些受过ACM、ICPC训练过的同学,尤其是那些能很快分析出问题复杂度的人。
         但是毕竟我不是科班出身,而且只在学校里面做过一些简单的网站项目,这让我在很长一段时间里都抱有一种误解,即认为工程能力和算法解题能力是不相干的两回事,佐证就在于有些人可以很轻松地解出一些算法题却无法用C#写一个真正可用的软件;而像我一样的人可以轻车熟路写出一个“看上去很美”的CMS系统,但面对一些课本上的算法题时却手足无措。而且更要命的在于,简单的网站做多了,我逐渐认为做工程不需要所谓的算法,算法好只能让人拿到更高的课程分数或是竞赛奖项,而在计算机科学这一非常讲究实践的领域中,只有良好的工程能力才有办法真正把某个项目实现。于是在很长一段时间里,我对那些能通过解出很难的算法题拿到很好offer的人都比较嗤之以鼻,并对那些公司的招聘标准感到疑惑不解——明明是我的实践经验和能力上更强,凭什么不要我而是他们呢?

    我觉得自己最大的幸运在于,随后的一些经历让我很快走出了这个误区。在本科的最后一个学期,我幸运地获得了一个前往微软亚洲研究院实习的机会(面试时考了我一道智力题而不是算法题),在实习过程中,我才“真正”地做了一个软件项目,并且通过和其他实习生的交流,“耳濡目染”地看到了许多现实中的研究性软件的开发过程,这些经历带给了我许多前所未有的体验。在现实的软件开发中你会看到各种形式各异的需求,比如在一定数量的帖子中找出发帖最多的“水王”,在这之前我开发过的网站最多也不过几千条记录,所以即使我简单地重复遍历所有记录也能实现这一功能,但是当你面对的是十万甚至百万级别的现实数据时,问题就从最基本的“实现”变成了“更快更高效地实现”了!令我感到汗颜的是,我往往只能用效率最低的复杂度实现类似的功能,而面对如何更优雅更高效地实现它时,我常常感到力不从心。

    这些经历让我逐渐意识到,我所沾沾自喜的工程实践能力实际上只是一种“实现”的能力,而在解决现实世界的实际问题时,更需要的是一种“优美的实现”,因为只有在可接受的时间或空间约束条件下的实现才是真正能解决问题的答案。而如何找到所谓的“优美的实现”,一个人算法能力在这里就起到了决定性的作用。算法实际上是对现实问题的抽象,因为现实问题是复杂的,我们可以把它抽象成模型。寻找合适的数据结构表示问题模型,并通过分析,寻找到对应的解决算法,这种抽丝剥茧的思维方式将会使得开发者事半功倍。那句著名的“软件=算法+数据结构”并非空穴来风,我也从这些经历中逐渐理解了微软等公司的招聘标准实际上没有错,因为他们需要找的是能真正通过分析解决实际问题的人。如果把工程实践能力比作一辆车的轮子,那只说明这辆车具有了移动的能力,而让这辆车能又快又稳的运行,则需要算法分析能力这台强劲的发动机驱动,这两种能力是相辅相成的。


    我觉得自己比较幸运的是,在我逐渐明白了这些道理后,参与编写了《编程之美》这本书。编书的过程也是我自己动手解里面一道道有趣题目的过程,期间我对一个个优美、巧妙的解法拍案叫绝,在遇到难题或想不通的时候,就通过与其他编者一起讨论解决,这些经历都让我不断体会到“解法之美”和“问题之美”。《编程之美》的许多题目实际上都来源于现实项目中所遇到的具体问题,它们或是实际问题的简化,或是改头换面以其他有趣的场景表示出来。但是万变不离其宗,通过把问题抽象化,并运用算法分析寻找解决方案将是解题的利器。这种思考方式也是我们希望通过本书传递给读者们的。祝大家能在阅读的过程中体会到“美”的无处不在。


[此贴子已经被作者于2008-4-16 8:45:13编辑过]

--  作者:netjian
--  发布时间:4/15/2008 1:03:00 PM

--  
读了《编程之美》,我才知道什么叫做美之编程。


[此贴子已经被作者于2008-4-16 8:56:23编辑过]

--  作者:bingling83
--  发布时间:4/15/2008 3:04:00 PM

--  
看了样章,好喜欢这样的书。先是给出一个问题留出空白让读者自己思考,然后给我若干种解法,让读者思考不同的实际情况选用哪种方法。最后还给出扩展问题,促使读者能举一反三。
--  作者:Humphrey
--  发布时间:4/16/2008 10:15:00 AM

--  
作为计算机科学与技术专业的学生,程序设计是必修课程,其重要性也是不言而喻的。我们都不会忘记,从最初简单的QBasic到复杂的C语言这样一个学期又一个学期的渐进过程。
我并不擅长程序设计,上学时尝试编制“马踏棋盘”不成,至今仍是心中的隐痛,但也促使我关注程序设计思想。以前这类书多以程序设计的风格和宏观设计理念为主,辅以实用技巧及心得,虽为金玉之言,却反复研读不得要领。这次初见本书样章,感觉如同一部习题解析,对各式各样的问题均进行解法剖析。国内常见的计算机程序设计教程普遍存在代码不完善,讲授简单,教学要求低的问题。思维僵化,变通能力受限造成了程序设计过程中难以发挥程序设计思想之所长,而只能服从一个模式,对于初涉程序设计的同志尤为如此。本书正好突破了这一瓶颈,在完备算法基础上介绍了对于同一个问题的多种解决方法,对试图通过类数据结构和算法的书中找寻编程灵感的同仁们有开阔思路的作用。
章节安排偏重数据结构和算法介绍,理论性很强;行文富于变化,对一些经典计算机谜题的解释令人忍俊不禁,足以使您坚定看下去的决心。一些问题除书中罗列的解题思路外还会有其他方法,作者将寻找这些方法的任务交给了您,在思考更好的实现方法的时候分析解决问题的能力也得到了提高。
阅读本书之前最好对数据结构和算法有基本了解,这样才不至于使您为突然接触到如此之多而又令人困惑的计算机谜题感到惶惑不安。并且不要把本书当作“代码速查手册”,书中只讲解问题的处理方法,具体实现要靠掌握一门高级程序设计语言。
--  作者:jiqing_gao
--  发布时间:4/16/2008 11:35:00 AM

--  
好书,就是与众不同,从不同的角度看问题
--  作者:showpower
--  发布时间:4/16/2008 11:47:00 PM

--  
看了一些题目,讲的确实不错,得好好看看。
--  作者:Qr
--  发布时间:4/17/2008 9:14:00 AM

--  
讲义风格,宛如板书;言简意赅,通俗易懂;算法灵活,分析透彻;语言生动,编程之美!
--  作者:凌鹰
--  发布时间:4/17/2008 4:05:00 PM

--  
感觉很适合求职的人用啊。
或者有算法基础的人可以用来练习一下,开拓思路,同一个问题提供多种解法和分析还是很好的。
--  作者:haozh502
--  发布时间:4/17/2008 6:21:00 PM

--  
踊跃参加
--  作者:xiaoyou8519
--  发布时间:4/18/2008 12:42:00 AM

--  
哈哈

我觉得编程的艺术在于品,一个人可以品茶,一个学生可以品题目,一个开发人员就能够品出一种境界.真正的大师属于这种.

一家之言


--  作者:ceny
--  发布时间:4/18/2008 10:01:00 AM

--  
粗略看了一下这本书,是一本很不错的书;
书中提到的那些算法不同于外面卖的那些算法书籍,
普通的书籍只是讲讲算法是什么,怎么写;
而这本书中提到的那些算法可算是一种程序的艺术结晶,
它将算法,技巧,实用性,以及应用数学融合在一起;
确实值得一看,也让人可以了解到微软的强大,并非只是依靠简单的垄断。
--  作者:hmpzz
--  发布时间:4/18/2008 10:14:00 AM

--  
太PF这些写书的牛人了现在看了这个样章才知道世界太大了,我连井底之蛙都赶不上
--  作者:boywaiter
--  发布时间:4/18/2008 3:10:00 PM

--  
看过样章,想起几个月以来身边找工作的朋友们互相交流的笔经面经,除了金刚以外,其他几个问题都仍然(并将继续)活跃在笔试面试现场。一点建议,给本书出版商,从经营的角度,似乎可以在校园巡回发布一下,影响更大。

--  作者:nirvana_2008
--  发布时间:4/18/2008 4:12:00 PM

--  

之前对算法的印象是晦涩难懂,每每总是望而却步,提不起来兴趣去研究算法,读了《编程之美》中的几个算法,有一种豁然开朗的感觉,原来算法也可以讲的这么生动有趣,这么吸引人。《编程之美》中的算法以实例开题,循序渐进的解决问题,一步步去剖析算法的本质,挖掘和发散算法功效,进而去淋漓尽致的体现算法的美妙!
--  作者:hjx_221
--  发布时间:4/19/2008 10:05:00 AM

--  
算法(Algorithm)是解题的步骤,可以把算法定义成解一确定类问题的任意一种特殊的方法。在计算机科学中,算法要用计算机算法语言描述,算法代表用计算机解一类问题的精确、有效的方法。
    算法常常含有重复的步骤和一些比较或逻辑判断。如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务;一个算法的优劣可以用空间复杂度与时间复杂度来衡量。
    《编程之美》贴近研发人员的实际,每个实例给出了若干个解题方法,这个恰恰就是我们所需要的编程方法的提示作用。读《编程之美》,就像在聆听一个经验丰富的编程高手在就某些有趣的问题侃侃而谈。
    愿《编程之美》的后续篇早日提上日程!!
--  作者:ZJupiter
--  发布时间:4/19/2008 1:54:00 PM

--  
支持!经过一次笔试,现在很想好好学习C++了!
--  作者:nirvana_2008
--  发布时间:4/19/2008 9:34:00 PM

--  
一口气把“不要被阶乘吓倒”和“寻找发帖水王”看完,意犹未尽,发现自己彻底喜欢上算法了,o(∩_∩)o...哈哈!《编程之美》不仅仅告诉我们一个问题是什么,即:“What”,关键是告诉我们如何去解决问题,如何去美妙地地解决问题,即所谓的“How”。
--  作者:Humphrey
--  发布时间:4/20/2008 3:08:00 PM

--  
书中问题涵盖范围极为广泛,网罗经典计算机谜题到生活实践问题;部分章节所附代码使人惊叹于算法实现的简单和高效;章末扩展问题也极具挑战性。这些问题和答案不知您想到没有?我可是没想到。
--  作者:gvtbs
--  发布时间:4/20/2008 9:05:00 PM

--  
今天无聊的快要不行了,在网上乱看乱打开一些网站,突然看到了本书。一开始看这个名就感觉很另类。编程之美,微软面试心得,我虽然不是什么编程高手但是以前看过微软的面试题都很独特也相当的有意思。于是呼就下载了样章看了起来。

  下了四个例子:中国象棋将帅问题,饮料供货,不要被阶乘吓倒,寻找发帖“水王”;看了一节后马上对本书起了浓厚的兴趣。这节的内容先不说算法怎么好,就说这语句用的是通俗易懂,而且例子和现实生活挂勾,讲例子和讲故事似的很吸引人。在问题的分析上相当到位使人毛色钝开,一点也不枯燥反而让人觉得很有好,好有意思的样子。

  看了一节后我破不急待的又看了下一节的内容,这里我已经深深的把这节的内容所吸引。我开始不停的咬我的圆朱笔头了(我一看到好东西种有这一个坏习惯,从小养成的)。看到了问题以后我就开始沉思了许久,在脑中想出了许多的解决方案。在心里盘算着那个方案是最优的,作者会是怎么解说的呢!在沉思过后把心里想的内容作上的笔记接着往下看。下面的内容出乎我的意料,有很多书本提出问题后就是重案了并没有怎么去分析,而这本书里却是把每种解决方案都分析了一下。我着着差不多和我想的大多相似,不过又有出点不同反正是说不出的喜欢。

  接下来一口气把那两个例子看玩了,把他的讲法相当的喜欢,只是我的底子差了点看的是一知半解的算法是明白了只是他里面把很多问题都数学化了有点脑子不够用的感觉。可能是我看的太快没有用心去想也有可能是我的基础太差的原因吧!

  看玩了这几个例子后还是有点一游未尽的感觉于是又在网上找了一下他的目录看了目录内容有点少了,哈哈要是能多点就更好了。
  下面来说点与内容无关的东西吧!!
  本书的排版很宽松让人看起来很舒服,不像别的书密密麻麻的都是文字。价格也相当的合适。本书以很有趣味的语言表棕了很想编程思想,本书对于有一定编程功底的人看效果将更加显助,像对于我这样的一般水平人员看有的时候就有点晕呼哈哈脑子不够用的感觉。


--  作者:mfc42d
--  发布时间:4/21/2008 9:58:00 AM

--  
我发表一下我的看法
这本书不是面试前的参考书,而是一本教我们如何解决现实遇到的各种问题,授人以渔,不是授人以鱼。
写程序是一种高智力的劳动,也就是解决编程中遇到的各种问题,但是你遇到的问题不是教科书出现的,但是可能是相似的。这就要求我们根据已有的知识解决现实的问题。
求二进制书中1的个数是一个很简单的问题,但是告诉我们解决一种问题通用做法。这就是在有限情况或者已知答案的情况下的通用做法。不适合未知情况,例如 求1000以内的水仙花数,明显的不适合,知道了我就不用求了。
曾经遇到一个这样的问题,做一个温度控制程序。
实际很简单,采集热电偶过来的电压,转为数字信号,根据这个信号现实测量的温度。
当时我们真的把这样一个方程算了出来,二阶微分方程,可以求解的,我花了一周的时间求出这个方程。
遇到问题是 我如何用51的汇编语言,把这个算法实现,51汇编语言功能不如8086汇编语言,当时还没有51的c编译器。在写了一个暑假的程序后,发现写出的程序根本无法达到设计的要求。后来我们经常用mathmatic求解微分方程,想到输入的电压是有范围的,AD(数字转为模拟)电路的值 也就是200多个,我们可以把200多个值使用mathmatic解出来,放在一个内存中,用的时候直接偏移量存取。最后终于证明这种方法是可行的。有时候我们需要的一种可行的方法而不是高效的方法,来解决现有的问题。
--  作者:krens
--  发布时间:4/21/2008 10:17:00 AM

--  
来晚了,也参加!
--  作者:348438345
--  发布时间:4/22/2008 5:09:00 PM

--  
积极参加!
--  作者:NullDream
--  发布时间:4/23/2008 3:48:00 PM

--  
编程之美——从中国象棋将帅问题说起

高中到大学期间看过不少算法书,从经典的《算法导论》,到比较新的Umesh的《Algorithms》、Tardos的《Algorthim Design》,都曾经细读过一段时间,这些书的一个特点就是很系统、正规,通常捧起来就能啃上一个下午。
  
一个偶然的机会在书店看到了《编程之美》,接触到了另一种教学风格。严格的说,这本书也不能算是算法书,因为里面涉及的知识范围不止是算法,比如有一道趣味题是解决如何控制CPU占用率曲线的问题,这和实际的编程联系的更为紧密,而通常的算法书更偏向于理论,甚至大多数算法都是用伪代码描述的。

这本书的一大特点就是首先给出一个易于描述和理解的常见问题,接着会给出若干种思维方式各异的方法,值得细细品味。

以“中国象棋将帅问题”为例,要求只使用一个代码输出所有将帅的合法布局位置。看到这道题,第一反应恐怕就是设计一个函数,使得两个二维坐标能用一个变量来表述,而解法一也采用了这种最直观的思想,利用了二进制把27*27个状态放到了一个整型中,定义了几个简单实用的宏(另外值得一提的是这本书对二进制的与、或、位移等操作使用得很漂亮,在其他例题中也能看到类似的精彩代码),然后通过这些宏用两重循环完成了各种状态的枚举。
  
另外值得一提的是,这本书的中代码都很简单明了,“寻找发帖‘水王’”中,给出了这样一个高效的算法后,如何实现又是一个问题。书上给出的这段代码只有短短十几行,却高效可行,毫不啰嗦,令人叹服。

总的来说,这本书的风格就是趣味轻快,却包含着大量知识,随手拿起看一两章就会有很大的收获。
--  作者:卷积内核
--  发布时间:4/23/2008 4:39:00 PM

--  
本书评转载自:http://blog.csdn.net/kabini/archive/2008/04/07/2256421.aspx

总体感觉是书中的内容没有“脱离群众”,很多都是我们平时生活、工作中经常能遇到的。题目不见得难,基本上给一本《算法导论》和足够的时间,大多数人都能解决其中的问题。但注意副标题--“微软技术面试心得”,这就给这本书定下一个基调:面对这些我们并不陌生、也并非特别困难的问题,在有限的时间里,(可能)比较紧张的心情之下,如何充分发挥自己分析问题和解决问题的能力,如何正确且漂亮地解决问题才是关键。我想,在平时学习的时候或许我们左手《算法导论》,右手《编程之美》效果会更好一些。

    关于"中国象棋将帅问题",该问题的具体描述是:(根据中国象棋的基本原则)在只有双的将帅棋盘上,找出所有双方可以落子的位置(将帅不能碰面),但只能使用一个变量。直觉上我们想到,只要遍历将帅所有可能的位置,去除将帅冲突的位置即可。可见,剩下的问题就在于如何使用一个变量来做二重循环的遍历。书中解法一给出的方法是将一个Byte变量拆成两个用,前一半代表“帅”可以走的位置,后一个变量代表“将”可以走的位置(事先已经将“将”和“帅”可以走的3*3的位置进行了编号),利用位操作即可获得两个计数器的功能。书中的解法三采用结构体来解决一个变量遍历二重循环的问题,思想上换汤不换药。真正有趣的是解法二,它的代码如下:

int var = 81;
while( var-- )
{
if( var / 9 % 3 == var % 9 % 3 )//发生冲突
continue;
else
printf(/** 打印可行的位置 **/);
}

当看到这个解法的时候,我心里有一些感慨。短短几行,体现了简约之美,虽然可能有牛人说这没什么了不起,但我觉得如果在面试这个问题的时候能写下这样的代码,我会很有成就感。在大多数时候我们无需知道希尔排序的时间复杂度的一点几次方是怎么算出来的,也无需去证明一个最优化问题是否满足“拟阵”的条件,我们只需要在这样一个“简单”的问题上做得漂亮,就够了。

回过头来分析这个解法。“将”和“帅”各在自己的3*3的格子间里面走动,我们共需要验证9*9=81种位置关系,这也是i=81的由来。此外我们要明白i/9和i%9的含义。我们知道,整数i可以由部两分组成,即var=(var/9)*9+var%9 ,其中var<n。我们注意到,在i从81到0变化的过程中,var%9的变化相当于内层循环,var/9的变话相对于内层循环。这样,作者就妙地用一个变量i同时获得了两个变量的数值。

简单即是美,相对于解法一的大段代码,我更希望我以后再面试中写出解法二。

其实这个问题还可以进行一些扩展,即如何利用一个变量达到三重循环的效果。也就是说,如果给定下面的循环:

int counter = 0;
for( int i = 0; i < 5; i++ )
for( int j = 0; j < 4; j++ )
for( int k = 0; k < 3; k++ )
{
System.out.println("counter="+counter+"\t, i="+i+", j="+j+", k="+k);
counter++;
}
其结果如下:
counter=0 , i=0, j=0, k=0
counter=1 , i=0, j=0, k=1
counter=2 , i=0, j=0, k=2
counter=3 , i=0, j=1, k=0
counter=4 , i=0, j=1, k=1
....中间略
counter=59 , i=4, j=3, k=2

问题是(1)我们如何用一个打印出相同的结果?(2)如果是N重循环呢?

面对第一个问题,实际上就是对原始的中国象棋将帅问题进行了一个扩展,即在棋盘上添加一个“王”,其行走规则和将帅 一样。于是棋盘变成了三国争霸:-) ,将帅王可以走动的格子数分别为3、4、5,它们之间的互斥条件可以按需要设定。

这时,就需要只用一个变量遍历一个三重循环。直观的方法是像方法一那样把一个4字节的INT拆开来用。我这里只关注方法二。

只用一个变量解决扩展的中国象棋将帅问题,我们的代码应该是如下的样子:
int var = 3*4*5;
while( var-- )
{
if( /** 冲突条件 **/ )//发生冲突
continue;
else
printf(/** 打印可行的位置 **/);
}

在冲突条件中,我们需要知道var取得某个特定的值(即第var+1次循环)的时候的i,j,k分别是多少(这样我们才能判定将帅位置是否冲突)

从上例的结果中我们可以看到,counter的值(即当前的循环次数)和三元组(i,j,k)是一一对应的,越是外层的循环变化越慢,他们满足什么关系呢?

k的取值最好确定,我们都知道是var%3。
在原始的将帅问题中我们知道,j的值应该是 var/3,但是由于j上面还有一层循环,就需要做些调整,变成var/3%4
最外层循环i的值则为(var/(3*4))%5.

即:k=var%3 //其下没有循环了
j=var/3 //其下有几个循环长度为3的循环
i=var/(3*4). //其下有几个循环长度为3*4的循环

于是4重循环的公式我们也可以轻松得出:
for( int i = 0; i < 5; i++ )
for( int j = 0; j < 4; j++ )
for( int k = 0; k < 3; k++ )
for( int p = 0; p < 3; p++ )

p=var%2 //其下没有循环了
k=var/2 //其下有几个循环长度为2的循环
j=var/(2*3)) //其下有几个循环长度为2*3的循环
i=var/(2*3*4)//其下有几个循环长度2*3*4的循环

下面就是一个变量实现三重循环
int var = 2*3*4*5;
while( var-- > 0){
System.out.println("var="+var+" , i="+((var/(2*3*4))%5)+
", j ="+((var/(2*3))%4)+",
k="+((var/2)%3)+",
p="+var%2);
}


结果是:
var=119 , i=4, j=3, k=2, p=1
var=118 , i=4, j=3, k=2, p=0
var=117 , i=4, j=3, k=1, p=1
...中间略
var=5 , i=0, j=0, k=2, p=1
var=4 , i=0, j=0, k=2, p=0
var=3 , i=0, j=0, k=1, p=1
var=2 , i=0, j=0, k=1, p=0
var=1 , i=0, j=0, k=0, p=1
var=0 , i=0, j=0, k=0, p=0

N重循环原理也是一样,就不再赘述了。


--  作者:conan_holmes
--  发布时间:4/23/2008 5:46:00 PM

--  
我看的是《寻找发帖“水王”》,初看此文感觉眼前一亮,让接触计算机多年的我感觉到一阵清新。原来计算机算法可以这么简单,而又这么富有技巧,相信这本书可以在轻松解题之余,提高每位读者对算法分析和设计的能力;而更重要的,使读者学会从不同常人的角度对求解问题进行巧妙抽象的思维。
--  作者:凌鹰
--  发布时间:4/24/2008 9:58:00 AM

--  
嗯,不错,拓宽思路了
适合对算法初步了解的人
--  作者:凌鹰
--  发布时间:4/24/2008 3:39:00 PM

--  
饮料那个,推导公式是不是写错了,
opt(V',i) = max{k*Hi + opt(V' - Vi * k, i-1)},应该是i+1吧,怎么是i-1呢

--  作者:yangzhj05
--  发布时间:4/24/2008 5:08:00 PM

--  
每看一个问题解法一,就迫不及待的看第二种解法!精彩!
--  作者:jason_00
--  发布时间:4/24/2008 8:59:00 PM

--  
本人书评:
概读本书,认为本书所给的问题有点类似信息学竞赛里的,即贴近生活,强调解决问题的能力。本书的一大特点就是先从一般思路来分析问题,但是却碰到效率问题,接着运用算法思想如分治,递推思路来解决效率瓶颈,其中分析过程循循善诱,如在其中一个问题”寻找发帖水网”,首先作者给出了先排序,在统计的常规思路,但是却碰到时间复杂度太高问题,作者首先从统计问题入手,利用了水王ID肯定是ID列表中间项,从而使统计的O(N)转为O(1).接着解决排序问题,又分析问题,发现如果删除列表里的两个ID,水王ID数还是超过1/2.最后作者来给问题来个点睛,认为从复杂问题转化简单问题,其中问题本质没有变,即水王ID在ID表的数量超过1/2.
本书对问题进行了点睛分析,如果读者思考问题之后再来阅读分析定能受益匪浅,本人认为本书可以作为算法课的课外辅助教材.阅完本书若能理解,体会作者分析问题,解决问题的思路,相信算法能力将有长足进步.总之本书是一本帮助读者提高用计算机解决问题能力的好书.

                                                                                                         Jason Hong


--  作者:Qr
--  发布时间:4/25/2008 8:56:00 AM

--  
中国的义务教育,完全是填鸭式的教育,很多书籍也存在同样的问题,但是,《编程之美》就不存在这个问题,没有被强迫接受的感觉,阅读过程完全处在一种轻松愉悦的状态,这样的阅读恐怕更容易接受吧,呵呵……
期待早日看到这本书……
--  作者:wangxiaomi
--  发布时间:4/25/2008 10:21:00 AM

--  
50楼的,这本书已经出版了。
--  作者:eDao
--  发布时间:4/25/2008 3:58:00 PM

--  
已经好久不写程序了,不知道还能不能看的懂哦,下载下来,鼓励一下自己。
--  作者:alex_le
--  发布时间:4/25/2008 7:58:00 PM

--  
《不要被阶乘吓倒》书评:
    虽是在讲数学理论,但语言给人感觉挺实在的。
    以一个问题开篇,从一开始便给了我探究问题的好奇,同时使我在读这章时有很强的目的性。问题如何解决?书中的方法是否跟自己所想的一样?...等等的疑问都能使我在读的时候集中注意力。不得不承认书中的方法很有创意。但是相关题目似乎跟阶乘关系不大嘛,还有很想知道作者在解决这些问题的时候是怎么一步步来寻找到答案的
--  作者:alex_le
--  发布时间:4/26/2008 8:48:00 AM

--  
《饮料供应》书评
      个人觉得有些地方似乎有问题:
       第二页,正文的第十四行的公式等号右边似乎应该为:max{k*Hi +Opt(V'-Vi*k,i+1)
          代码清单1-9中,参数变量type似乎在代码中没有作用
       第三页最后一段“不需要opt[i][j+2]”不太理解,似乎没有出现过

--  作者:KID2HL
--  发布时间:4/27/2008 1:49:00 PM

--  
有机会看看,貌似很神奇的样子。
--  作者:Qr
--  发布时间:4/28/2008 8:24:00 AM

--  
以下是引用wangxiaomi在2008-4-25 10:21:00的发言:
50楼的,这本书已经出版了。


今天就可以拿到这本书,先睹为快了,呵呵
--  作者:eastdream99
--  发布时间:4/28/2008 8:51:00 AM

--  
谢谢楼主
--  作者:冬天的农夫
--  发布时间:4/28/2008 10:07:00 AM

--  
看了第一期的,个人认为,这本书好似数据结构与算法的补充实习题。没有什么新意,如果没有事情做,当当练习也还是个不错的选择。
--  作者:gvtbs
--  发布时间:4/28/2008 11:00:00 PM

--  
开什么国际玩笑 conan_holmes 和 jason_00 写的有什么好的,我就认为我写的比他们的要好的多为什么没有中奖不公平啊
--  作者:gvtbs
--  发布时间:4/28/2008 11:01:00 PM

--  
今天无聊的快要不行了,在网上乱看乱打开一些网站,突然看到了本书。一开始看这个名就感觉很另类。编程之美,微软面试心得,我虽然不是什么编程高手但是以前看过微软的面试题都很独特也相当的有意思。于是呼就下载了样章看了起来。

  下了四个例子:中国象棋将帅问题,饮料供货,不要被阶乘吓倒,寻找发帖“水王”;看了一节后马上对本书起了浓厚的兴趣。这节的内容先不说算法怎么好,就说这语句用的是通俗易懂,而且例子和现实生活挂勾,讲例子和讲故事似的很吸引人。在问题的分析上相当到位使人毛色钝开,一点也不枯燥反而让人觉得很有好,好有意思的样子。

  看了一节后我破不急待的又看了下一节的内容,这里我已经深深的把这节的内容所吸引。我开始不停的咬我的圆朱笔头了(我一看到好东西种有这一个坏习惯,从小养成的)。看到了问题以后我就开始沉思了许久,在脑中想出了许多的解决方案。在心里盘算着那个方案是最优的,作者会是怎么解说的呢!在沉思过后把心里想的内容作上的笔记接着往下看。下面的内容出乎我的意料,有很多书本提出问题后就是重案了并没有怎么去分析,而这本书里却是把每种解决方案都分析了一下。我着着差不多和我想的大多相似,不过又有出点不同反正是说不出的喜欢。

  接下来一口气把那两个例子看玩了,把他的讲法相当的喜欢,只是我的底子差了点看的是一知半解的算法是明白了只是他里面把很多问题都数学化了有点脑子不够用的感觉。可能是我看的太快没有用心去想也有可能是我的基础太差的原因吧!

  看玩了这几个例子后还是有点一游未尽的感觉于是又在网上找了一下他的目录看了目录内容有点少了,哈哈要是能多点就更好了。
  下面来说点与内容无关的东西吧!!
  本书的排版很宽松让人看起来很舒服,不像别的书密密麻麻的都是文字。价格也相当的合适。本书以很有趣味的语言表棕了很想编程思想,本书对于有一定编程功底的人看效果将更加显助,像对于我这样的一般水平人员看有的时候就有点晕呼哈哈脑子不够用的感觉。


--  作者:Qr
--  发布时间:4/29/2008 8:52:00 AM

--  
以下是引用gvtbs在2008-4-28 23:00:00的发言:
开什么国际玩笑 conan_holmes 和 jason_00 写的有什么好的,我就认为我写的比他们的要好的多为什么没有中奖不公平啊


重在参与!admin不是说以抽奖方式来发放奖品吗,同时还允许多次发贴,说不定你也能抽中哦

--  作者:gvtbs
--  发布时间:4/29/2008 10:31:00 AM

--  
说说怎么个抽奖法,按什么抽的,我看是版主选谁就是谁了吧!
--  作者:admin
--  发布时间:4/29/2008 11:16:00 AM

--  
以下是引用gvtbs在2008-4-29 10:31:00的发言:
说说怎么个抽奖法,按什么抽的,我看是版主选谁就是谁了吧!

说明一下,获奖名单是由出版社方面(即本次活动的赞助方)确定的。并非我个人想让谁拿就让谁拿的:-)


[此贴子已经被作者于2008-4-30 1:15:38编辑过]

--  作者:冬天的农夫
--  发布时间:4/29/2008 1:39:00 PM

--  
学好数据结构和算法,离散以及组合数学就可以了。这本书我觉得实在没有什么意义。随便一个题目,都可以在我说的这三个方面找到对应。而且不但知道其然也知道其所以然。
--  作者:蝶影
--  发布时间:4/29/2008 5:59:00 PM

--  
我是从连连看这个游戏开始看的,原因是我一直都很喜欢玩连连看,每次玩的时候都会在想究竟这个游戏是怎么实现出来的,看了这本书,我得到了一个比较完整的解答。
      平时学习各种各样的算法,然而却总是不知道什么时候该用什么,一点透了,又恍然大悟。我觉得这本书在这方面,给了大家很好的启发。我想,把平时学习的东西通过通俗的例子说明它的应用,是这本书最精妙的地方,就好像学画画一样,并不是只知道线条的画法和颜色的调配就能画出好画,更重要的是线条和颜色的搭配,同样地,编程并不是课本上的基础知识练就的,更重要的是知道在什么情况下,该用在哪里,这些是需要不断思考,练习和积累的。我想,通过这本书给的例子以及基本的解答,读到的不仅是编程的精妙之处,还有对编程的理解,学习和积累。
      感谢作者带来这样一本好书!
--  作者:Pthinker
--  发布时间:4/29/2008 8:36:00 PM

--  
这本书不错,很实用
--  作者:tomcatwilson
--  发布时间:4/29/2008 10:03:00 PM

--  
我目前的研究方向是系统软件,以及编译器优化技术,对算法一向是不怎么感冒的,因为导师一直对google招人的笔试方式很不以为然,慢慢的随着自己在实验室做研究经验的积累,慢慢的已经开始有点认同他的看法了。算法虽然优美,但是也不能走极端,为了优美而优美,忽视了底层系统软件和体系结构的支持是不可取的。不过我对编程之美中的各种有意思的算法题目还是很感兴趣的,至少在闲暇之余拿来把玩一下,对于锻炼自己的思维能力还是很有好处的。

比较同意前面zellux的一种看法:衡量一个算法实际效果不单要看复杂度,还要结合其他情况具体分析。尤其是当我看到求二进制中1的个数解法四,查表法复杂度O(1)的时候简直要吐血。这难道是算法追求的终极之美?不敢苟同。其实CMU还有一门经典的课程简称ICS,Introduction to Computer System--in programmer's perspective,(zellux提供的一个位算法可以从ICS的Lab作业中找到影子)如果把这本书作为一顿美餐的原材料,那么Introduction to Algorithms就是将这些原材料做成美味大餐的配方,如果再加上《编程之美》中题目作为调味剂,一个六星级程序大厨就这么诞生了,管他MS还是Intel,IBM,Google都可以游刃有余的。

其实我一直都想找这么一本以实例为基础的算法书作为自己的调味剂,而偶遇编程之美恰恰给了我这个机会,不过对待书中的一些为了追求唯美算法而没有考虑系统的地方还是颇有微词的。比方说求10进制1的数目这个题目,一扎眼就发现google曾将它作为的一道面试题(孰先孰后这里不再论证)原题目如下:
Consider a function which, for a given whole number n, returns the number of ones required when writing out all numbers between 0 and n. For example, f(13)=6. Notice that f(1)=1. What is the next largest n such that f(n)=n?
以下是一个目前发现的最高效的算法,虽然比很多算法看起来要长许多,但是它不止是得到199981,它把4000000000内的所有都遍历出来了。而且速度还只是几十毫秒,或者更快。书中的第一问的算法2,里面用到了switch,这个在系统编程里面是很忌讳的,因为他要查跳转表,这个东西是要访存两次的。访存的开销是很大的。目前针对JVM中的interpreter的很多优化就是想办法把解释器中的庞大的一个switch想办法替换成更为有效的方式,所以很多人提出了改变class文件的bytecode的编码方式,由基于栈的转成基于寄存器的。
本题目中用到的case数目不是很多所以感觉上差距不会很大,但是这里我只想说明,算法再怎么高级也要考虑到系统和体系结构方面的东西,否则就有可能是空中楼阁,海市蜃楼。
建议就是希望书再版的话,多加入一些系统方面的探讨。胡言乱语了一番,希望不要被bs....
   1. #include "stdafx.h"  
   2.   
   3. #include <windows.h>  
   4. #include <stdlib.h>  
   5.   
   6. int f(int n);  
   7. int count1(int n);  
   8. int cal(unsigned int number,int nwei,int count1,unsigned int ncount);  
   9.   
  10. int gTable[10];  
  11. const unsigned int gMAX = 4000000000L;  
  12.   
  13. int main(int argc, char* argv[])  
  14. {  
  15.   int i;  
  16.   unsigned int n=1;  
  17.   unsigned int ncount = 0;  
  18.   int nwei = 0;  
  19.   int ncount1;  
  20.   
  21.   /*if(argc>1)
  22.   {
  23.     n = atoi(argv[1]);
  24.     ncount = f(n);
  25.     printf("f(%d) = %d\n",n,ncount);
  26.   }*/  
  27.   
  28.   int beginTime=GetTickCount();  
  29.   //init gTable  
  30.   for(i=0;i<10;++i)  
  31.   {  
  32.     n *= 10;  
  33.     gTable[i] = f(n-1);  
  34.   }  
  35.   
  36.   n=0;  
  37.   nwei = 0;  
  38.   ncount1 = 0;  
  39.   while(n<gMAX)  
  40.   {  
  41.     unsigned int temp;  
  42.       
  43.     temp = 1;  
  44.      
  45.     ncount =cal(n,nwei,ncount1,ncount);  
  46.     for(i=0;i<nwei;++i)  
  47.       temp *= 10;  
  48.     n += temp;  
  49.     if( (n/temp)/10 == 1)  
  50.       ++nwei;  
  51.     ncount1 = count1(n);  
  52.   }  
  53.   
  54.   int endTime=GetTickCount();  
  55.   endTime-=beginTime;  
  56.   
  57.   printf("time: %d ms\n",endTime);  
  58. return 0;  
  59. }  
  60.   
  61. int f(int n)  
  62. {  
  63.   int ret = 0;  
  64.   int ntemp=n;  
  65.   int ntemp2=1;  
  66.   int i=1;  
  67.   while(ntemp)  
  68.   {  
  69.     ret += (((ntemp-1)/10)+1) * i;  
  70.     if( (ntemp%10) == 1 )  
  71.     {  
  72.       ret -= i;  
  73.       ret += ntemp2;  
  74.     }  
  75.     ntemp = ntemp/10;  
  76.     i*=10;  
  77.     ntemp2 = n%i+1;  
  78.   }  
  79.   return ret;  
  80. }  
  81.   
  82. int count1(int n)  
  83. {  
  84.   int count = 0;  
  85.   while(n)  
  86.   {  
  87.     if( (n%10) == 1)  
  88.       ++count;  
  89.     n /= 10;  
  90.   }  
  91.   return count;  
  92. }  
  93.   
  94. int cal(unsigned int number,int nwei,int count1,unsigned int ncount)  
  95. {  
  96.   int i,n=1;  
  97.   unsigned int maxcount;  
  98.   if(nwei==0)  
  99.   {  
100.     ncount += count1;  
101.     if(number == ncount)  
102.     {  
103.       printf("f(%d) = %d \n",number,number);  
104.     }  
105.     return ncount;  
106.   }  
107.   for(i=0;i<nwei;++i)  
108.     n *= 10;  
109.   maxcount = ncount + gTable[nwei-1];  
110.   maxcount += count1*n;  
111.   if(ncount > (number +  (n-1)) )  
112.   {  
113.    return maxcount;  
114.   }  
115.   if(maxcount < number)  
116.   {  
117.     return maxcount;  
118.   }  
119.   n /= 10;  
120.   for(i=0;i<10;++i)  
121.   {  
122.     if(i==1)  
123.        ncount = cal(number+i*n,nwei-1,count1+1,ncount);  
124.     else  
125.        ncount = cal(number+i*n,nwei-1,count1,ncount);  
126.   }  
127.     return ncount;  
128. }



--  作者:冬天的农夫
--  发布时间:4/29/2008 10:37:00 PM

--  
以下是引用admin在2008-4-29 11:16:00的发言:
[quote]以下是引用gvtbs在2008-4-29 10:31:00的发言:
说说怎么个抽奖法,按什么抽的,我看是版主选谁就是谁了吧!
[/quote]

说明一下,获奖名单是由本次活动的赞助方电子工业出版社博文视点决定的。并非我个人想让谁拿就让谁拿的:-)


看来我的置疑是无法被选中了


--  作者:冬天的农夫
--  发布时间:4/29/2008 10:45:00 PM

--  
to tomcatwilson
我觉得你说的很有道理。
我也是觉得这本书有很大的问题。
我还是觉得要具体问题具体分析。
要看应用环境。
就拿计算有多少个1那道题。
还是要看时间和空间的平衡。
空间换时间这种思想,最经典的应该是散列了。这本书还是可以说一下,这个思想的应用的环境,比如linux的shell命令注册(如果我没记错的话)。
总之,不能单纯追求算法的美妙。
不过,确实这本书的算法也都是比较经典的。
但是,感觉在夸这本书的人都没有仔细看过什么算法书。
--  作者:冬天的农夫
--  发布时间:4/29/2008 10:47:00 PM

--  
以下是引用alex_le在2008-4-25 19:58:00的发言:
《不要被阶乘吓倒》书评:
     虽是在讲数学理论,但语言给人感觉挺实在的。
     以一个问题开篇,从一开始便给了我探究问题的好奇,同时使我在读这章时有很强的目的性。问题如何解决?书中的方法是否跟自己所想的一样?...等等的疑问都能使我在读的时候集中注意力。不得不承认书中的方法很有创意。但是相关题目似乎跟阶乘关系不大嘛,还有很想知道作者在解决这些问题的时候是怎么一步步来寻找到答案的

这个方法哪里有什么创意。。。


--  作者:tomcatwilson
--  发布时间:4/29/2008 11:18:00 PM

--  
所以我说这本书作为调料,来调节枯燥的code生活还是很不错的
但是要明白,能量守恒这个问题,时间和空间是有个tradeoff的
--  作者:jason_00
--  发布时间:4/30/2008 12:15:00 AM

--  
tomcatwilson,农夫都是牛人,向你们学习---
不过谈点我的看法:做应用软件开发是不削于底层的细节,本书的算法改进都是数量级的改变,所以自然有其美丽之处,而组织的改变会随着硬件的发展而不断改进,不过依赖于硬件本身的就另当别论
--  作者:tomcatwilson
--  发布时间:4/30/2008 9:04:00 AM

--  
啥牛人不牛人的,牛人都不会像我这样在这里吹牛了^_^
其实做应用的很多也很少在考虑精妙的算法的,能实现就行了,当然google这种地方可能除外,在中国,iter都是民工,能完成任务就行啦,反正公司和项目都不是我的。希望不要被达人们鄙视,羞愧中。。。
--  作者:冬天的农夫
--  发布时间:4/30/2008 9:15:00 AM

--  
以下是引用tomcatwilson在2008-4-30 9:04:00的发言:
啥牛人不牛人的,牛人都不会像我这样在这里吹牛了^_^
其实做应用的很多也很少在考虑精妙的算法的,能实现就行了,当然google这种地方可能除外,在中国,iter都是民工,能完成任务就行啦,反正公司和项目都不是我的。希望不要被达人们鄙视,羞愧中。。。

呵呵 貌似这又涉及到软件工程中的实现那阶段的问题了。
我又看了几章。觉得这书可以算是算法书中的科普类读物。
叫《算法之美》到是不错。
我没有全部看完,在我看到的几章中没有涉及到“如何写代码”的细节。
呵呵 算法书中的《苏菲的世界》。



--  作者:alex_le
--  发布时间:4/30/2008 9:31:00 AM

--  
《1的数目》
有几处似乎有点问题:
第五页正文第五行:f(23)->f(123)
第十、十一页:关于指数的描述不是很清晰
想提个建议: 问题2的求解时,关键不等式得出显得突然了点,能不能把思路具体讲下

--  作者:冬天的农夫
--  发布时间:4/30/2008 11:17:00 AM

--  
以下是引用alex_le在2008-4-30 9:31:00的发言:
《1的数目》
有几处似乎有点问题:
第五页正文第五行:f(23)->f(123)
第十、十一页:关于指数的描述不是很清晰
想提个建议: 问题2的求解时,关键不等式得出显得突然了点,能不能把思路具体讲下



书上写错了,应该是f(10^n - 1) = n * 10^(n - 1);
而不是f(10 ^ (n - 1)) = n * 10^(n - 1); // 注意和上面对比多了括号
使用数学归纳法容易证明。
证明:
当n = 1时有
f(9) = 1, 成立。
设f(10^n - 1) = n * 10^(n - 1)成立,
下面证明f(10^(n+1)-1) = (n+1)*10^n
因为:
f(10^(n+1)-1) = f(10^n - 1)*10 //第一部分,后面解释
                                  + 10^n // 第二部分, 后面解释
第一部分: 0...10^(n+1)-1序列中所有的数去掉最高位,即第n位(没有到n位补零), 有10个0...(10^n) - 1序列。
第二部分: 这10个0...(10^n) - 1序列中还原最高位为1,需要补(10^n)个1。
于是
f(10^(n+1)-1) = f(10^n - 1)*10 + 10^n =( n*10^(n-1))*10 + 10^n = (n+1)*10^(n+1 - 1)
得证

打字很累



--  作者:tomcatwilson
--  发布时间:4/30/2008 11:31:00 AM

--  
真是个辛勤的农夫啊 呵呵
--  作者:卷积内核
--  发布时间:4/30/2008 3:30:00 PM

--  
以下是引用tomcatwilson在2008-4-30 9:04:00的发言:
啥牛人不牛人的,牛人都不会像我这样在这里吹牛了^_^
其实做应用的很多也很少在考虑精妙的算法的,能实现就行了,当然google这种地方可能除外,在中国,iter都是民工,能完成任务就行啦,反正公司和项目都不是我的。希望不要被达人们鄙视,羞愧中。。。

关键该书书名后面还有一个副标题---微软技术面试心得,其实该书就是结合实例讲解算法而已,编程过程中可能你并用不到,你写的这些算法在应聘Microsoft成功后也可能还是用不到,但是我认为关键的一点是考到了你的数学方面的能力,有可能书中解法一、解法二...一直到解法N让你看的感觉精妙绝伦,这些解法有可能依然不是最好的解法。还有一个就是考到了你的创新思维,如果在本书中列举的所有算法中你在Microsoft或者其他公司面试中又考到了,你给出一个创新的算法,但并不是已有算法中最好的,你也可能面试PASS。
还有一点就是“编程高手”都喜欢对大家都知道的问题给予新奇的解法,大家看到后自然就感觉到“高手就是高手”了。其实这些都是数学算法的游戏,本书也许就是让读者从游戏当中体验编程之美吧。


--  作者:ICT_RemyChan
--  发布时间:4/30/2008 4:09:00 PM

--  
不错,很有趣的一本书
看有没有时间试试第四期
--  作者:Qr
--  发布时间:4/30/2008 6:02:00 PM

--  
以下是引用冬天的农夫在2008-4-30 9:15:00的发言:

呵呵 貌似这又涉及到软件工程中的实现那阶段的问题了。
我又看了几章。觉得这书可以算是算法书中的科普类读物。
叫《算法之美》到是不错。
我没有全部看完,在我看到的几章中没有涉及到“如何写代码”的细节。
呵呵 算法书中的《苏菲的世界》。



昨天收到这本书后,仔细看了前面几章,部分赞同你这个说法。但我也不否认这本书,虽然书中的示例在现实工作中并不起多大作用,然而它呈现给读者的是不同的编程理念,对于读者来说,在读过这本书后,你得到了什么,这才是最重要的,它会在你今后的编程中会给你一种无形的推动,只是你不一定觉察到。如果各位要学习算法,这本书不是最好的。
--  作者:tomcatwilson
--  发布时间:4/30/2008 6:27:00 PM

--  
达人讲的看不出跟我说的有什么联系,咋引用我的帖子了呢?
以下是引用卷积内核在2008-4-30 15:30:00的发言:
[quote]以下是引用tomcatwilson在2008-4-30 9:04:00的发言:
啥牛人不牛人的,牛人都不会像我这样在这里吹牛了^_^
  其实做应用的很多也很少在考虑精妙的算法的,能实现就行了,当然google这种地方可能除外,在中国,iter都是民工,能完成任务就行啦,反正公司和项目都不是我的。希望不要被达人们鄙视,羞愧中。。。
[/quote]

关键该书书名后面还有一个副标题---微软技术面试心得,其实该书就是结合实例讲解算法而已,编程过程中可能你并用不到,你写的这些算法在应聘Microsoft成功后也可能还是用不到,但是我认为关键的一点是考到了你的数学方面的能力,有可能书中解法一、解法二...一直到解法N让你看的感觉精妙绝伦,这些解法有可能依然不是最好的解法。还有一个就是考到了你的创新思维,如果在本书中列举的所有算法中你在Microsoft或者其他公司面试中又考到了,你给出一个创新的算法,但并不是已有算法中最好的,你也可能面试PASS。
还有一点就是“编程高手”都喜欢对大家都知道的问题给予新奇的解法,大家看到后自然就感觉到“高手就是高手”了。其实这些都是数学算法的游戏,本书也许就是让读者从游戏当中体验编程之美吧。



--  作者:zhuomuniao2
--  发布时间:5/4/2008 11:47:00 AM

--  
好东西,学习下
--  作者:冬天的农夫
--  发布时间:5/5/2008 10:42:00 AM

--  
又看了此书的几章。
感觉比较适合刚毕业的大学生或者刚学完数据结构算法的学生。
从这个角度讲,这本书确实不错。
同意Qr,这本书确实不是学习算法的好书。
不过应该是应用算法的好书。
有一点建议:
再版的时候,把用到的算法思想以及使用这个算法的原因告诉读者。
--  作者:jason_00
--  发布时间:5/6/2008 12:33:00 PM

--  
今天终于拿到书了,看了三个问题---,感觉本书的确是一本不可多得的好书,不仅在分析问题上起到很好的引导作用,而且对编程实现上的技巧也有很多总结性的启发,反对那些眼高手低的人---,不管你有多厉害,本书在某些方面还是很有启发性---
--  作者:冬天的农夫
--  发布时间:5/7/2008 2:01:00 PM

--  
大家都来看看《寻找最大的K个数》中的问题6:“精确度”问题。有点意思。
--  作者:卷积内核
--  发布时间:5/7/2008 4:16:00 PM

--  
以下是引用冬天的农夫在2008-5-7 14:01:00的发言:
大家都来看看《寻找最大的K个数》中的问题6:“精确度”问题。有点意思。

恩,这问题是很有意思,涉及到我们最普通的应用“网页搜索”。看后感觉是不是百度也是这么做的呢?有时搜索完毕前几页并不是最想要的,相反后面几页会找到更符合的答案。以前感觉还挺疑惑的,现在和这个联系起来倒是有几分道理了。


--  作者:冬天的农夫
--  发布时间:5/7/2008 7:26:00 PM

--  
以下是引用卷积内核在2008-5-7 16:16:00的发言:
[quote]以下是引用冬天的农夫在2008-5-7 14:01:00的发言:
大家都来看看《寻找最大的K个数》中的问题6:“精确度”问题。有点意思。
[/quote]

恩,这问题是很有意思,涉及到我们最普通的应用“网页搜索”。看后感觉是不是百度也是这么做的呢?有时搜索完毕前几页并不是最想要的,相反后面几页会找到更符合的答案。以前感觉还挺疑惑的,现在和这个联系起来倒是有几分道理了。


老大也有这个感觉?
呵呵

我觉得
他既然用的是多路 归并
很可能最先几趟是严格按照大小顺序排列(用个败者树什么的)
到后面就不是那么 严格

不过 如何不严格 但保证在忍受范围之内 就是要好好思考的事情了


--  作者:sweepthesky
--  发布时间:5/7/2008 7:48:00 PM

--  
下载了一口气看了几个问题,感觉确实是一本颇有启发性的书,和市面上一般的算法书不同,当然我也同意楼上观点,这并不是纯算法书,而是结合实例来设计应用算法知识,应该说趣味性很强。
没有参加过MS的面试,感觉如果是这样难度的题那自己在算法方面一定得多加强了。
另外本书的风格很好,很适合循序渐进的思考,我看的几个问题都是从低效代码入手,分析了复杂度,指出了低效的原因,再引导读者去找高效算法,很不错,建议有一定算法基础的人都可以读一下,一定会有启发!
--  作者:xjs1231
--  发布时间:5/8/2008 1:31:00 PM

--  

今天在逛csdn无意中看到的,很不错的书。之前看过 程序员面试攻略 那本书,觉得不错。而且我在找工作面试的过程中,确实就遇到过很多类似的。现在看了这本书,更是如获珍宝。

说说第4期的 判断链表相交的问题:
之前有过类似的问题就是判断一个链表有没有环,那个很简单,设置2个不同的步进指针就可以了。看到这个判断相交的问题,我就说说我对第一个扩展问题的想法吧
   如果有环且相交的话,那这2个链表的形式就象一个带2跟挂带的手镯一样的了。中间是个死循环,所以判断链表结尾是行不通的,所以至少需要2个指针来作为退出条件的判断。所以我的思路是: 从A出发2个指针,一个步进一,设为A1,一个步进二,设为A2,从B出发2个指针,同样一个步进一,B1,一个步进二,B2。
   A的2个指针先出发,如果有A2为空了,则没有环。A2守在这儿,等B的指针。 如果A1 == A2, 有环,且相等的地方必为环上的某一个结点。把A2指向A1的下一个结点(这样确保B的指针能在第一时间内与A的指针碰头,如果相交的话)。同样,守在这边。
   B的2个指针出发,边走边判断和B2是否与A1和A2中的一个相等。如果相等则相交。同时要判断B1 是否等于 B2。如果相等则B上有环并且与A没有相交。B2为空,判断是否与A2相等,如相等则相交。不等则不相交。


--  作者:xjs1231
--  发布时间:5/8/2008 1:52:00 PM

--  
刚才上厕所的时候想了一下链表的扩展问题二,思路如下:
先各设一个指针,算出2个链表的长度,设为M, N. 然后把2个指针重新指向链表头,长的链表的指针先走 |M - N|个结点,然后2个指针同时走,当2指针相等的时候, 就是重合的部分的开始。
--  作者:DMman
--  发布时间:5/10/2008 12:58:00 PM

--  
有些朋友早就向我推荐这本书了,今天下载了第4期的内容看了看。感触还是很大的。不仅启发我们解决问题的思路,而且也培养我们发现问题的意识。不错的书!
   1 先看了“瓷砖铺地板”的问题,上一阵去北京看到了希格玛大厦,呵呵,看到这个题目还是蛮亲切的:)“问题出于实际”我们学了这么多年的数学、微积分等,又解决过什么实际问题呢?认识不到一门知识的具体用途时,是学不好这门知识的。这道题建立的差分方程,使我回忆了一大阵当年学过的差分方程的完整解法。本道题目解法不难想到,给我最深的感触就是“学问来自实践”,门捷列夫小时候在玻璃厂工作,看到工人们将不同的物质加入玻璃中形成了不同的颜色与性能,才激发出他认识化学元素的念头,我们很多人从小就被送进学校,有多少人学的都是纸上谈兵的功夫?
   现在那么多吊天花板、镶地板砖的工作者,恐怕没有想到这么多,莫非就是从一个角开始铺,到最后铺不开的话就砸成半个?
   想到一本”Ruby“的书序中,大致意思是程序员都喜欢做有兴趣的事情,最讨论枯燥的开会,一开会就打瞌睡,趁机休息下,或者在脑子里想刚才编程中遇到的问题。而该书的作者却会想:为什么开会这么枯燥呢?难道不能让它设计得有趣吗?
   2 链表相交的问题中指出“实际编程设计工作中,有时需要相交的链表,在释放之前需要我们慎重”。虽然暂时想不到什么情况时需要设计相交的链表,但这个问题无疑是在实际研究开发中提出来的,而且我们以后的开发设计工作中可能也会用到相交链表。同样说明,没有实践,没有深入到动手,发现不了新的问题,甚至新的理论、方法。“相交链表”难道不是一项创新么?厚积而薄发,空想是不会掉馅饼的。
  by the way,楼上的朋友谈的寻找两个无环链表的第一个交点的思路好像不是正确的?。
  以遍历的方法在O(length(h1)*length(h2)*)的时间复杂度内是可以解决的。在看了“计算字符串相似度”问题后,可以考虑:这个问题如何用分治法或动态规划法实现?
   3 从“字符串的相似度”看分治法与动态规划法
   文中给除了分治法的解决方法,同时提出了问题:如何解决重复计算问题?这无疑指出了该问题适合于动态规划法的一个特征:子问题重叠。很多朋友都搞不清楚分治与动态规划的区别。我谈谈自己的一点看法。
   两者都是把大问题分割成子问题,但分治把问题分成的子问题是独立的,而动态规划不是独立的。我们可以理解为分治用递归实现,动态规划用递推实现,后者的显著特征就是“以空间换时间",记录了中间的计算结果。
   假设strA=(A1,A2,...Am)strB=(B1,B2,...Bn),以c[i,j]表示strA[i..m]和strB[j..m]之间的距离,即问题求解c[1,1]。
    由该文中叙述的思路得到
c[i,j]=0 如果i=m+1或j=n+1;
c[i,j]=c[i+1,j+1]如果i<m+1,j<n+1和strA[i]=strB[j]
c[i,j]=max(c[i+1,j+2],c[i+2,j+1],c[i+2,j+2])+1 如果i<m+1,j<n+1和strA[i]!=strB[j]
由此建立算法:
m<-length(strA)
n<-length(strB)
for i<-1 to m
   do  c[i,n+1]=0
for j<-1 to n
   do  c[m+1,j]=0
for i<-m downto 1
  do for j<-n downto 1
      do if str[i]=str[j]
          then c[i,j]=c[i+1,j+1]
          else c[i,j]=max(c[i+1,j+2],c[i+2,j+1],c[i+2,j+2])+1

c[1,1]即为所求


[此贴子已经被作者于2008-5-11 19:09:34编辑过]

--  作者:gvtbs
--  发布时间:5/11/2008 11:11:00 AM

--  
上一次写的书评没有得奖心里不平死了!!只能用一句话总结这本书,完美有味是一本好书!!
--  作者:DMman
--  发布时间:5/11/2008 6:59:00 PM

--  
“子数组最大乘积”中体现的“抓住问题本质”的精神
  我觉得,这个题目并非受过高等教育,系统学习过算法等相关计算机理论的人才能理解或者解答;同时,即使是大学生也不一定能够解答小学数学寒假作业中的思考题!
  首先,谈谈中国对创新意识的忽略和扼杀。记得从高中时候开始,漫天喊着“发散思维,要创新”!正像有一年的高考作文题目“答案是丰富多彩的”,似乎也正是这个时候,国人开始逐渐肯定教育中的创新意识。有篇文章讲的故事:有一个寓言,主要是说小羊成功的识破了大灰狼的乔装打扮,没有被吃掉;有个学生说寓意是做一件事情要充分准备才能成功,而标准答案是要认真观察才能识破敌人的阴谋,该生不仅没得分,还受到了批评。我曾经有个小学同学,二年级的时候就在自己的小房间里安了个小灯泡,用打开门时角度的大小控制灯的亮度,就是这个一个动手能力强的奇才,因为考试成绩差而不得不在四年级时辍学,现在在家开了个修理摩托车的店。我的结论是,培养创新人才,教育至关重要,引导至关重要,一本好书也至关重要!读研以前,在我16年的学生生涯中,我还极少看到引人入胜的学习书籍,无不是在枯燥和应付中度过。这使我们失去的不仅是知识,而且还有自信。相信很多朋友虽然学了不少书,抑或也编了不少程,但谈起算法的考察仍然会心虚不已,也时常质疑:到底什么是算法?哪里才能用到算法?
  “子数组最大乘积”的解决中,症结直指时间复杂度和空间复杂度,这也是算法要解决的本质。能解决问题和能更好的解决问题,往往是凡人和高手的区别。对于高考数学来说,很多人都觉得时间不够用:如果在给我足够的时间的话,我能得到更高的分数。其实,在解题过程中,一般人都会按部就班的进行,而高手往往能静思继而发现问题的本质,从而后发而先至,提高了解题速度。显然“子数组最大乘积”能够在O(n^2)的时间复杂度内完成,但线性时间复杂度的解决方案不是更令人拍案惊奇么?
  这本书能够带领我们多角度的思考问题,是一种不可多得的收获。读者可否觉得:这些思路我也能看懂,但为什么我想不到呢?创新是一种意识,从而成功成为一种习惯。相信这本书能够有力的培养读者多角度的思考习惯,从症结看问题的思考习惯,提高读者“抓住问题本质”的习惯和能力。


--  作者:Humphrey
--  发布时间:5/13/2008 3:01:00 PM

--  
等待着,等待着……
我等待着我的奖品,一本有生以来第一次网络活动的奖品
——属于我的《编程之美》

--  作者:xjs1231
--  发布时间:5/13/2008 3:48:00 PM

--  
心情同 Humphrey

另外 To DMman:
关于无环求交点的问题,你那个方法稍稍有点复杂吧,我那个思路的复杂度我觉得应该是
O(Length(m) + length(n) + ...), 这个是加号不是乘号呢。
大概思路为:

M:            --------
                             |
                               ------------
                             |
N:    ------------
N步进到这: ^ , 即 |length(m) - length(n)|.
然后同时步进,直到2个指针相等^
其中没有任何嵌套的操作,所以就不会有乘法运算了。
欢迎继续讨论。:)


--  作者:DMman
--  发布时间:5/13/2008 6:21:00 PM

--  
恩 你说得对 我把相交的定义理解成交叉了
--  作者:kofssl
--  发布时间:5/15/2008 9:03:00 PM

--  
谢谢lz,一定好好看
--  作者:hunter2236
--  发布时间:5/16/2008 9:56:00 AM

--  
多谢,多谢!!
--  作者:xjs1231
--  发布时间:5/19/2008 6:07:00 PM

--  
感谢,今天已经收到书了。
--  作者:oyzp
--  发布时间:5/20/2008 3:32:00 PM

--  

--  作者:wg4308
--  发布时间:8/1/2008 9:53:00 AM

--  
偶在书店里看见了 !
的确挺不错的书 !!
--  作者:Dennis.Wang
--  发布时间:11/13/2008 3:18:00 PM

--  
刚看了书中的第一个题目 数1的数目
3种解法我都有想到,只是第三种和作者的总结略有不同
我的想法是:既然可以把实际问题抽象成数学问题,我们也可以认为是一个哲学问题:
以题目为例(10进制) ,数1的数目和数0~9中的任意个数字的数目是一样的(或者称公平性),
注意:我值得不是算法,而是一种对称性。然而之所以结果不对称是因为每一个数字在一个整数数列范围内的排布的不对称性。
有了这个思想后再解题目的时候就会有另外的抽象了吧(我是把它抽象为空间几何了)
--  作者:kooo
--  发布时间:11/30/2008 5:50:00 PM

--  
我也来支持一下
--  作者:秋十三
--  发布时间:3/7/2009 9:06:00 PM

--  
呵呵
顶一下啊
--  作者:ansin
--  发布时间:5/2/2009 11:59:00 PM

--  
子数组的最大乘积一问题中对于P为正数的讨论似乎没有完全,忽略了数组中所有数字都为负数且个数是偶数的情况,此时,应该删除数组中绝对值最大的负数。

这本书讨论的算法很有启发意义,不过很多似乎都是在竞赛中讨论过的问题,不过很欣赏这种渐进式的解决问题的写法。


--  作者:JMsun
--  发布时间:3/24/2010 11:53:00 PM

--  感觉好像《计算字符串的相似度》的源代码错了。
在计算t1,t2,t3的时候,至少begin增加一位。
这样例如“ABCD” 和“EFCD”,出来的相似度好像是不正确的应该有2处不一样,但是犹豫跳过了第2位,所以结果是1。
不知道我这样的判断是否正确?
--  作者:wangqujian
--  发布时间:5/21/2010 2:29:00 PM

--  
不错的
W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
625.000ms