V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
caijj
V2EX  ›  随想

学习新语言(算法)的时候对于阅读他人的代码和自己写(思考)之间的把握

  •  
  •   caijj · 2013-03-08 05:49:52 +08:00 · 2161 次点击
    这是一个创建于 4284 天前的主题,其中的信息可能已经有所发展或是发生改变。
    传统来说应该都是先自己思考然后思考不出来再上网找答案吧?
    但是思考多久呢?

    比如说最近在学lisp 以前只碰过c和java
    基础的语法掌握的差不多了,看到一些入门题
    写一个无限长度的 prime lazy-sequence

    以前从没有实现过关于质数的算法,对于质数的理解只有他的定义
    稍微想一下最白痴的办法就是2到n/2都没法整除就是质数了
    再思考下大概可以缩小到测试 2到n^(1/2)
    再往上的算法凭个人大概短时间想不出来了,我查了下Sieve of Atkin这个算法大概算最快的之一吧
    思考到什么程度好呢? 如果说思考到想不出来更好的方法的话, 大概sieve of atkin我也能花几年的时间想出来吧如果必须要做的话。

    实现方面不同的算法肯定不一样 相同的算法也应该会有最优解。自己独立做到什么程度好呢?





    总的来说就是学习的时候到底应该参考网上的资料到什么程度呢? 从最基础的语法到完整的实现网上肯定都有。但是什么都不查大概抓破头也写不出来,就算写出来了要不要优化呢? 优化到什么程度呢?查的话到什么程度又是个问题。
    6 条回复    1970-01-01 08:00:00 +08:00
    y
        1
    y  
       2013-03-08 06:18:53 +08:00
    当然可以学习别人的算法啦,经典算法本身就是好例子。
    我不认为你想个几年能想出 Sieve of Atkin 或者比他更好的方法。

    但是可以慢慢实践,或者对于一些简单的问题,reinvent the wheel。比如你说的方法,其实是试除法,下一步可以只用小于 √n 的素数试除,更好的办法还有筛法,筛法的要点是用加法代替了乘法。具体怎么 implement 和优化就考验你的水平了,比如简单的,wheel, bitarray 等等。真想学还有一个办法就是看着 TAOCP 做题,你要知道,作者让你做的题都是确定能做出来的,50分的除外。下多大功夫就看你意志力了。(或者,学 Scheme 的话,做 SICP, 不要用 Common Lisp, 里面已经有太多现成的东西了,不适合学习,还有一些结构上的原因。)
    caijj
        2
    caijj  
    OP
       2013-03-08 10:11:45 +08:00
    @y
    其实我在学clojure不过这不是重点。

    假如说世界上90%的问题都是有解的, 最简单的题的最简单的解大概5s就想出来了,最难得题的最优解可能要耗费一生的时间去研究。而且由于每个人智商,擅长方向不一样,所需要的时间也不一样。

    那么什么时候应该学习,利用前人已有的成果, 什么时候又应该自己尝试呢?
    比如你说的筛法。我从来没有听说过。也许凭我的智商要一周或者更久才能想出来。
    也有可能我花一周的时间想出来比Sieve of Atkin更好的方法。
    你认为我想几年也想不出来,我也这么认为的。因为你不了解我,我也不了解自己。而概率来讲很大可能我确实没有这个能力或者耐心。
    但是当时可能也没有人认为发明Sieve of Atkin的人可以发明出来。

    刚刚又查了一下到底什么是学习,怎么学习。
    In short, learning through try and fail can be good, but only when it teaches us lessons that we couldn’t learn otherwise. There is a big difference between educated failing and fumbling your way through life unprepared.

    看起来很有道理,但是也只是笼统的说做什么而不是怎么做。
    当然每个人都是独立的,没有规则对所有人都管用,就像同样的算法实现也会有差距。
    但是还是会忍不住去想界限到底在哪里。 自己尝试的界限vs学习前人的界限。

    表达能力不好,想到哪里就写到那里.. 见笑了
    感觉好多东西往深处走就是哲学的范畴了.. 脑子很混乱
    y
        3
    y  
       2013-03-08 10:35:18 +08:00
    @caijj 学习方法这个东西确实不好讨论。你要是有兴趣就想想求素数的方法吧,也没人拦着你。想出来运算速度低于 O(N/loglogN) 的,可以通知我,我请你吃饭。要是你一周之内有成果,算是有慧根了。算法复杂度这一领域有很多好问题等着你做。

    或者这样吧,按实际操作。既然你写的是 Lisp,你要是能在任何 implementation 里写一个函数 sieve, 在低于 3GHz CPU, 不考虑 print 的时间,单核 0.3s 内跑出2亿以内素数,我请你吃饭也行。[用

    > (time (progn (sieve 200000000) ()))

    来计时] 这个估计算法和优化都考到了,而且是个很苛刻的要求
    (我自己的 Macbook pro 上 (mid 2010, 2.4GHz),
    SBCL 里一个十行代码的 sieve,需要 4.9s.
    我相信优化一下缩短一半的时间是不难的,0.3s 就是四次 “一半”。)
    caijj
        4
    caijj  
    OP
       2013-03-08 22:45:22 +08:00
    @y
    我不是来讨论这个具体的算法的..
    我是想讨论下关于学习的方法。我举的例子只是想说明个体的差异性,而不是来炫耀我有多聪明可以写出多快的算法(事实上我在前面也说了我也不认为自己能写出来)所以我不太理解你给我的这些题是什么意义。 是说与其思考如何学习不如just do it么?

    再往外推论的话不仅是学习编程,算法。 学习任何新东西的时候对于实践和观察的取舍。
    这才是我想讨论的
    kshatriya
        5
    kshatriya  
       2013-03-08 23:12:13 +08:00
    我觉得学习一门新的语言, 最关键的一点就是要揣摩设计者的心理, 理解语言设计的意图. 函数式是另一端的表达方式, common lisp里面的宏实在是太nb了. 你在看书或者看范例的时候一定要把自己带入情景中去, 具体的我也说不上来, 这个东西太主观了. 至于优化, "不要过早优化", 先达到目的, 之后有性能工具之类的, 有瓶颈的时候再去考虑优化.

    如果有条件, 尝试实现一个lisp解释器也是不错的体验
    y
        6
    y  
       2013-03-09 01:20:02 +08:00
    简直是浪费我金币啊。

    一开始看你的意思,好像是别人研究成果,不知道该不该学,还是直接拿过来用。“也有可能我花一周的时间想出来比Sieve of Atkin更好的方法。” ————我的意思就是,你要是真有这种乱拳打死老师傅的本事,就做呗,一个礼拜也不算浪费你时间。(当然,算法的渐进行为 (Asymptotic behavior) 可不是乱搞出来的,运算次数需要证明。)

    其实拿过来用的过程,也是一个学习的过程。比如某个步骤你不会,但是你实践过,没准什么时候就想通了。其实 Sieve of Atkin 的道理也很简单,就是二次域上素数的分解,用二次型的方法判断而已,都是 19 世纪的数学,只是从算法的角度看比较好而已。

    “因为你不了解我,我也不了解自己。” 没经过判断打击人是我不好,
    那我就针对具体问题进一步,给了 benchmark,且请你拿实力出来说话。

    =========

    学习任何新东西的时候对于实践和观察的取舍这本身就是从实践中来的,空谈没有任何帮助。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3483 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 04:56 · PVG 12:56 · LAX 20:56 · JFK 23:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.