菜鸟求教:怎么学才能让自己从零开始写出下面这种水平的算法来?(or 求教如何学算法?)

2018-12-28 11:01:53 +08:00
 NotreDame

不是那种看别人现成的代码理解之后写出来,而是完全没听过,只给需求就能慢慢写出来这种。自己想达到的水平如下面贴出的。而自己现在处于:按自己思路写出的漏洞百出,改好这个 bug,又出新 bug 的水平。别说优雅了,下面这种难度的算法,完全给自己实现,都不能正确搞出来。。。

/**
     * 二分查找法变种 floor, 在有序数组 arr 中, 查找 target
     * 如果找到 target, 返回第一个 target 相应的索引 index
     * 如果没有找到 target, 返回比 target 小的最大值相应的索引, 如果这个最大值有多个, 返回最大索引
     * 如果这个 target 比整个数组的最小元素值还要小, 则不存在这个 target 的 floor 值, 返回-1
     *
     * @param arr
     * @param target
     * @return
     */
    static int floor(Comparable[] arr, Comparable target) {
        // 寻找比 target 小的最大索引
        int l = -1, r = arr.length - 1;
        while (l < r) {
            // 使用向上取整避免死循环
            int mid = l + (r - l + 1) / 2;
            if (arr[mid].compareTo(target) >= 0) {
                r = mid - 1;
            } else {
                l = mid;
            }
        }
        assert l == r;
        // 如果该索引+1 就是 target 本身, 该索引+1 即为返回值
        if (l + 1 < arr.length && arr[l + 1] == target) {
            return l + 1;
        }
        // 否则序列中无 target, 该索引即为返回值
        return l;
    }
2511 次点击
所在节点    问与答
24 条回复
TomVista
2018-12-28 11:53:17 +08:00
打好基础,这个就不算算法. 虽然他是,但是你总不能把类似于冒泡排序这种东西称之为算法吧.

还有算法这东西一般大家都用现成的:dog
visitant
2018-12-28 12:00:25 +08:00
说完全没听过我是不信,二分查找都没听过,逗我玩吗
subpo
2018-12-28 12:29:41 +08:00
这代码优雅在哪儿...
Raisu
2018-12-28 12:54:04 +08:00
买一本 数据结构与算法 入门教材,把里面的数据结构都自己实现一遍,了解每种数据结构基本操作的复杂度,刷 LeetCode 的 easy。
买深入一点的 算法教材, 把里面几个基础的算法思路都了解一遍。再刷一遍 LeetCode。
sylxjtu
2018-12-28 12:57:24 +08:00
二分算法边界情况很多,初学者背下来是最方便的
Caturra
2018-12-28 13:12:37 +08:00
完全没听过说明你基础不行

建议买本通俗易懂的算法书花两三天粗略扫一遍然后找 OJ 刷题
hexingb
2018-12-28 13:14:12 +08:00
其实你面对的是两个问题:一是对算法的理解;而是开发能力。如果你 i 理解二分法,能写出上面变种算法的大体结构却漏洞百出,说明你其实开发能力欠缺。
提升方法么,无非多读书、多思考、多实践。
tt67wq
2018-12-28 13:15:36 +08:00
欧拉计划刷到 100+ 算法就算入门了
NotreDame
2018-12-28 13:48:53 +08:00
@TomVista 应该是多刷题吧,虽然都是用现成,但是我想能自己慢慢的一点点由简单到困难的写出来。
NotreDame
2018-12-28 13:50:46 +08:00
@Raisu 很感谢您的答案,切题,而且指导性、可行性非常高,感谢感谢。打算就这么开始干了。
Yiki
2018-12-28 13:51:16 +08:00
盲目追求优雅不好吧..
NotreDame
2018-12-28 13:52:28 +08:00
@sylxjtu 嗯嗯,就是对各种边界情况感到困惑,作为初学者,常常感叹人家作者当初是怎么想出的。
NotreDame
2018-12-28 14:03:15 +08:00
@Caturra okok 可行可行,谢谢。
NotreDame
2018-12-28 14:04:41 +08:00
@Yiki 目前不追求,我本意还是请教大家,怎么正确学算法。
NotreDame
2018-12-28 14:07:38 +08:00
@hexingb 你说的很对,一针见血。尤其边界问题总是有纰漏。
NotreDame
2018-12-28 14:07:59 +08:00
@hexingb
visitant
2018-12-28 16:23:02 +08:00
就像楼上说的,先了解基础算法吧,基础算法实现一遍了解一下思想就差不多了,那些复杂的算法我每次看都会感概人和人之间差距真大
Yiki
2018-12-28 16:44:47 +08:00
想不到楼主对[优雅]意见这么大……
我的话就是大三学 C 版数据结构,大四看了 Java 算法把代码都弄懂到红黑树那一块了
然后……我就当了前端狗- -~
maplelin
2018-12-28 17:24:55 +08:00
不知道楼主是怎么定义代码好坏的。写代码的时候遵循一定原则,一般都是在保证功能足够简洁代码尽量抽象的前提下,保证逻辑和调理清晰,然后能够针对意外情况和一些异常做出处理。这个还是经验和素养的问题。
NotreDame
2018-12-28 18:49:44 +08:00
@Yiki 不是我意见大,是感觉大家有点跑题,我解释一下而已。。。说实话,我看不出什么特别优雅不优雅的,只是感觉有的代码很干净,不拖拉。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/521807

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX