最近面试,按说候选人背景也都不错吧。
我们对算法要求没那么高,业务代码为主。
因此对于各种语言的候选人,我基本都会问一道长整数加法的问题。
俩数相加,都没有符号 /没有小数点 /字符串表示 返回和 /用字符串表示
这题难吗?
考察的知识点点挺广的:
字符串 /数组操作,循环控制,流程逻辑,边界条件等等。
这也基本上是编程的时候经常能遇到的问题。
但是我遇到的面试者写的千奇百怪的都有:
idx ** 10等等吧
所以如果你遇到这个题,如何优雅的写一个 a+b?
稍后我写一个我自己花了一小点时间写的答案,八行,没有很过分的压缩代码 我的代码大概长这样:
function add(a, b) {
    let ...
    some magic {
    	cast something
        cast other
    }
    return ...
}
正经逻辑三四行写完,晚一些我贴条的方式公布我的答案。
如果要你写,你写啥?
|      1islxyqwe      2020-08-20 11:07:07 +08:00  5 const add = (a,b)=>(BigInt(a) + BigInt(b)).toString() | 
|      3march1993      2020-08-20 11:08:45 +08:00 via iPhone 都字符串了 那就按字符串按位拼呗… | 
|  |      4luckyrayyy      2020-08-20 11:10:00 +08:00  2 我应该就是啰啰嗦嗦那种了。循环,字符取一位,转成 int,相加,记录进位,剩余的转回 str 加到结果上。 | 
|      5Jooooooooo      2020-08-20 11:11:57 +08:00 我理解写 a+b 如果是 string 就是考察最基本的代码能力 如果是 int 那考察思考全面性 (溢出怎么办? | 
|  |      6dartabe      2020-08-20 11:13:16 +08:00 我咋看好多答案都用的 bigint | 
|      7phpfpm OP @Jooooooooo 溢出就 try-catch 一下吧,前置判断没啥意思了 @dartabe big int 用了我考啥。。。我也是反复强调不能用(当然绝大多数面试者不知道 hhh ) 主贴写的时候写漏了。 @march1993 @luckyrayyy 真的写一下估计会漏一些情况(比如最后的进位) | 
|      8hytex      2020-08-20 11:18:39 +08:00 怎么感觉是字符串相加的那个题… 按位取余多的进 1,然后叠加就行了啊… | 
|      10lijialong1313      2020-08-20 11:19:54 +08:00 字符串 /数组,反转处理不好吗…… 而且不能转 number 的话,难不成是两个字符串加起来之后减去对应的值?( C 语言) | 
|      11DL9412      2020-08-20 11:21:29 +08:00 这不是上周的每日打卡题么,模拟竖式就完事了 | 
|      12phpfpm OP @lijialong1313 c 处理 atoi 也确实可以这么干 主要是反转吧必要性没那么大 太多人只会正着写 for,不会反着写 for,不会写 while ; 或者你要用 map-reduce 之类的方法把字符串先 reverse 我还能忍 @hytex 话是这么说,欢迎提供代码~ 能贴条的时候我补充我的版本。 | 
|      14hytex      2020-08-20 11:26:12 +08:00 @phpfpm 格式我不会弄这个,每日一题我做过这个。 public String addStrings(String num1, String num2) { int a = num1.length() -1 , b = num2.length() - 1 , add = 0; StringBuffer ans = new StringBuffer(); while(a >= 0 || b >= 0 || add != 0 ) { int x = a>=0 ? num1.charAt(a) - '0' : 0; int y = b>=0 ? num2.charAt(b) - '0': 0; int res = x + y + add; add = res / 10 ; ans.append(res % 10); a -- ; b --; } ans.reverse(); return ans.toString(); } | 
|      15lijialong1313      2020-08-20 11:26:59 +08:00  1 @phpfpm 主要是不反转的话,对于最左的进位就需要额外的一次移动所有字符串操作( c 语言),我做 oj 遇到这种都是习惯反着处理。 | 
|  |      17yhxx      2020-08-20 11:28:54 +08:00 import { BigNumber }  from 'big-number'; return BigNumber(a).add(b); (手动滑稽 | 
|      18phpfpm OP | 
|      19lijialong1313      2020-08-20 11:31:36 +08:00 @phpfpm 那这样的话,这玩意儿应该满地都是大数加法算法了吧( C 语言) | 
|      23phpfpm OP @lijialong1313 满地都是大数加法算法了吧——没跟上。 我们不招 c 的,不过有年头比较长嵌入式北京的我会随口问一句 C 的 VLA 形如 ``` struct foo { char bar; int[0] baz; }; ``` 这个 trick 了 (我也只会这个了 hhh | 
|  |      24no1xsyzy      2020-08-20 11:39:36 +08:00 | 
|      25islxyqwe      2020-08-20 11:39:48 +08:00 addr 0 [] xs = reverse xs addr n [] xs = addr 0 (show n) xs addr n xs [] = addr n [] xs addr n (x:xs) (y:ys) = (addr left xs ys) ++ (show digit) where (left, digit) = divMod ((read [x] ::Integer) + (read [y] ::Integer) + n) 10 add a b = addr 0 (reverse a) (reverse b) | 
|  |      26ytmsdy      2020-08-20 11:41:24 +08:00 via iPhone 我记得当年刚刚开始玩 acm 的时候,zoj 上的第一道题就是大数 a+b 。那时候花了快 3 天才搞完! 现在想想,从最后一位开始模拟手工计算的过程就好了! | 
|  |      27cyrbuzz      2020-08-20 11:41:52 +08:00 ```       function add(a, b) { let max = Math.max(a.length, b.length); a = a.padStart(max, '0'); b = b.padStart(max, '0'); let result = '' let pad = 0 for (let i=max-1; i>-1; i--) { let c = String(Number(a[i])+Number(b[i])+Number(pad)) c = c.padStart(2, '0') pad = c[0] result = `${c[1]}${result}` } return `${pad === '0' ? '' : pad}${result}` } console.log(add('1001', '200')) ``` | 
|  |      28no1xsyzy      2020-08-20 11:42:25 +08:00 | 
|      30phpfpm OP @no1xsyzy  @cyrbuzz @ytmsdy @islxyqwe @no1xsyzy @hytex @lijialong1313 @yhxx @dartabe @Jooooooooo @luckyrayyy @march1993 @islxyqwe 我在贴条 Append 的地方写了我的解法了——很遗憾,那边好像不支持 markdown 。。 ``` function add(a, b) { let pos = 0, res = '' while(a.length > pos || b.length > pos) { let carry = res.length - pos++ res = (~~a[a.length - pos] + ~~b[b.length - pos] + carry) + res.substring(carry) } return res } ``` 希望回复能好看点。。。。 | 
|  |      31no1xsyzy      2020-08-20 11:55:27 +08:00 @phpfpm #30 APPEND 需要自己选择语法是 Default 还是 Markdown 这个用 res.length 来记录是否有进位有点奇技淫巧了 | 
|  |      33no1xsyzy      2020-08-20 11:58:27 +08:00 @phpfpm #30 也不能说奇技淫巧,就是在各种地方找到能放信息的地方 还是 add(x,y) = x&y<<1 + x|y 更奇技淫巧…… | 
|  |      34no1xsyzy      2020-08-20 11:59:45 +08:00 @banishee #32 唯一处理数组的地方是取 a[] 和 b[],JS 下溢出是 undefined, ~~x 之后就是 0,这点上无法替换为 +x,因为 +x 会变成 NaN | 
|  |      35murmur      2020-08-20 12:00:21 +08:00 有大整数类为啥要自己写,你能保证写出来的过的单元测试比库更多么 | 
|  |      36wutiantong      2020-08-20 12:02:21 +08:00 std::string add(std::string a, std::string b) { std::string result; auto a_i = a.rbegin(), b_i = b.rbegin(); char ten = 0; while (true) { char x = 0; if (a_i != a.rend()) x = (*a_i++) - '0'; char y = 0; if (b_i != b.rend()) y = (*b_i++) - '0'; auto c = x + y + ten; if (c == 0) break; else if (c > 9) { c -= 10; ten = 1; } else ten = 0; result.insert(result.begin(), c + '0'); } return result; } | 
|      37lijialong1313      2020-08-20 12:02:52 +08:00 @phpfpm 我写了一个 c 语言的: https://paste.ubuntu.com/p/YjF5DZqXnR/ | 
|  |      38YuTengjing      2020-08-20 12:09:48 +08:00 via Android 这道题很常见啊,不会做说明没怎么准备面试算法 | 
|  |      39XiaoxiaoPu      2020-08-20 12:12:04 +08:00 确实不难吧,我大一就能做高精度浮点数的加减乘除、三角函数、指数、对数函数了,虽然效率一般。 | 
|  |      40mazyi PRO 面试笔试做不出长整数加法的是不是 coding 能力就基本当没有了? | 
|  |      41talen666      2020-08-20 12:26:09 +08:00 两个字符串相加??做业务跟这个关系不大。。 | 
|  |      43shuigui      2020-08-20 12:28:55 +08:00 是的,这个是基本逻辑能力 | 
|  |      44shm7      2020-08-20 12:33:12 +08:00 就是基本逻辑吧,不要随便问个题目想看看你脑子转不转,就上纲上线。 | 
|  |      45shm7      2020-08-20 12:33:59 +08:00  1 我觉得你说的这个输入 2 字符串算结果输出字符串都做不好,那真是没有什么编程能力了。 | 
|  |      46XisucksYi      2020-08-20 12:34:47 +08:00  1 知道這個有什麼意義? 語言只是工具, 可以完成任務就行, 不能強轉, 不能用 built-in, 我想問下這樣弄有什麼意義. 我覺得你和面試者聊這種沒意義的東西是你會被打死. | 
|      47sampeng      2020-08-20 12:41:19 +08:00 via iPhone  1 你这叫没过分压缩代码?写成一行才算? | 
|      48672795574      2020-08-20 12:47:45 +08:00 | 
|  |      49peapods      2020-08-20 12:48:51 +08:00 via Android  1 很多面试真的就是玩弄一些奇技淫巧,用一个随便一搜就能解决的问题来刁难面试者,每天被狗屁项目经理(领导)逼着搬砖写各种 bug 还不够么。问题来了,一个茴香豆有几种写法? | 
|      50sampeng      2020-08-20 12:48:54 +08:00 via iPhone @XisucksYi 那如何在面试中判断一个人的逻辑能力呢?当然我没过分到要用笔试。比如我最喜欢问的。用 a 去分割字段 b 。不许用内置函数。是不是比楼主这种简单 100 倍。答得上来的成功率不超过 20%用两种以上思路的…em 。二十个里面有一个吧 | 
|  |      51ChenFanlin      2020-08-20 12:49:12 +08:00 | 
|  |      52jmc891205      2020-08-20 12:49:20 +08:00 加法太 straightforward 了,没什么好讨论的 乘法还可以 | 
|  |      53hikarugo      2020-08-20 12:49:28 +08:00 还行吧,看什么时期,应届生是好题,社招见仁见智吧 | 
|      54phpfpm OP | 
|  |      57czzhengkw      2020-08-20 12:53:09 +08:00 吓得我赶紧试着写了一下,还好,能写出来 | 
|      58sampeng      2020-08-20 12:55:21 +08:00 via iPhone @phpfpm 对啊…而且我都没说手写,说说思路就行…就是这么夸张…所以楼主简单的算法题过滤人完全没问题…感觉现在是用人市场,找工作的比招聘的多得多。所以择优选择一点毛病没有 | 
|      59phpfpm OP @ChenFanlin  @jmc891205 @fyxtc 这个我校招社招都问过,区分度区别不大。 在学校瞎混的和社招写了几年代码事儿都忘光的都有。 简单题。。要是乘法的话估计一般来说没半个小时写不完,我面试时间一共才 45min,等不起,而且区分度更差。 本质上我这边招人还是要能自己 coding 的,再牛的人来该干活还是得干活。 @672795574 你的意思是这里也有产品混进来吧 懂你懂你。 | 
|  |      60murmur      2020-08-20 12:57:01 +08:00  3 @reus  有滴滴为什么考驾照?因为不是什么时候都有滴滴,但是我什么时候都能搜到第三方库 而且我这岂止是滴滴,这滴滴还有个接单 10w 无事故的老司机,怎么说都是滴滴爽 如果类比的话,去的公司禁止使用源,不准使用外部网络和代码,所有算法自己手写,可能有这个实际需求 | 
|  |      61dartabe      2020-08-20 12:58:28 +08:00 确实是 leetcode 里面 easy 题里面都算简单的 | 
|      62phpfpm OP | 
|      63672795574      2020-08-20 13:07:49 +08:00 我倒是挺好奇,会这题的人,有觉得楼主面试问这题没有意义么 | 
|      64nznd      2020-08-20 13:08:27 +08:00 常用 python 的我 第一反应想出来的就是基础的模拟按位加法,然后一想 python 无限长度 int 都可以加,就去看了下实现 https://github.com/python/cpython/blob/2d264235f6e066611b412f7c2e1603866e0f7f1b/Modules/_decimal/_decimal.c 现在在怀疑人生 | 
|      65phpfpm OP | 
|      66phpfpm OP | 
|  |      67XisucksYi      2020-08-20 13:13:51 +08:00 我要是面試官的話, 我出冒泡排序題, 寫出來的我肯定過濾掉這種人的, 因為知道怎麼寫的肯定事先了解過冒泡排序,  說明他平時浪費時間搞這些算法, 我可不想跟這種書呆子做同事. | 
|  |      68shilyx      2020-08-20 13:15:03 +08:00 直接面试求 100 的阶乘得了 | 
|      69672795574      2020-08-20 13:20:36 +08:00 @phpfpm DP 是个好题目,本身的框架就几行,看看对方怎么得出递推公式,有来有回交流一下,思路 /沟通都可以看出来。我被问得最多的也是 DP.. | 
|      70phpfpm OP | 
|      71phpfpm OP @672795574 等我结束这个阶段招聘之后我单独写一个 dp 的面试技巧(从面试官的角度) 本质上来说我(现在面试招聘的岗位)不需要算法大牛(业务属性相关),希望面试者具有聪明+思维严谨的属性。 当然如果是其他业务需求考察 dp 就更难了,比如剪枝优化等等,leatcode 偏难的题目的思路: 硬钢肯定超时,不优化的 dp 过不去几个点,优化到一定程度才能 AC 。 | 
|  |      72XisucksYi      2020-08-20 13:28:51 +08:00  3 | 
|      74crazycarry      2020-08-20 13:32:52 +08:00 看到你的回复了,真把自己当个菜?还面试官,,真当自己是个官了。是哪个大厂的?要是垃圾厂别笑死人了 | 
|  |      75tigren      2020-08-20 13:34:46 +08:00 我应该属于啰哩啰唆的那种的,遥记得第一次写的时候我写的是右边对齐,然后从左边开始一位位加,做完面试官表示很无语:虽然你这不算错,但是感觉这么别扭 | 
|  |      76CismonX      2020-08-20 13:42:33 +08:00 via iPhone 我大三的时候面字节跳动实习岗位的时候让我手写大数乘法,要求优于平方时间复杂度,然后我给他写了个 karatsuba 算法,他看了看不满意(可能写的不太对),然后我跟他说我还知道有个 toom-cook 算法,但是不会写。然后就没有然后了。。 | 
|  |      78XisucksYi      2020-08-20 13:43:31 +08:00 | 
|      79jlak0106      2020-08-20 13:44:01 +08:00 是挺垃圾的,大厂估计没这闲功夫在这发帖吧 | 
|  |      80wutiantong      2020-08-20 13:49:48 +08:00 @wutiantong 上面写得有点问题。。。 std::string add(std::string a, std::string b) { std::string result; auto a_i = a.rbegin(), b_i = b.rbegin(); char ten = 0; while (a_i != a.rend() || b_i != b.rend()) { char x = 0; if (a_i != a.rend()) x = (*a_i++) - '0'; char y = 0; if (b_i != b.rend()) y = (*b_i++) - '0'; auto c = x + y + ten; if (c > 9) { c -= 10; ten = 1; } else ten = 0; result.insert(result.begin(), c + '0'); } return result; } | 
|  |      81InkStone      2020-08-20 13:51:00 +08:00  1 我觉得你第二个贴条写的那个高精加挺烂的 评价代码好无非是两种标准,一种是清楚,一种是高效。拿代码长短去评价代码是否优秀,给人的感觉就像是既不做工程也不会底层 | 
|  |      82XisucksYi      2020-08-20 13:53:11 +08:00 @jlak0106 我不知道他是不是創業的小廠 CEO, 如果是的話, 他真的在浪費時間, 活該創業失敗. 我遇到很多創業的合夥人都是這樣, 一直皎潔這些沒意義的東西, 一副書生氣, 自己被算法噁心過還要噁心下面試的人, 又抱怨招不到人. 書生能做什麼大事呢? 書生輕議塚中人, 塚中笑爾書生氣罷了 | 
|      84jlak0106      2020-08-20 13:58:08 +08:00  2 @XisucksYi 我们组去年来了大神,不爱说话,天天在那看算法,还神经算法,让他自己都说不清楚,进来写个业务代码,bug 多的触发测试环境复盘。每个人都有自己的兴趣和钻研方向,不能你喜欢算法,别人不喜欢,写不出来就 coding 能力就基本当没有,楼主是人身攻击???自己怎么不去算法岗位去试试!! | 
|  |      85Panic      2020-08-20 14:00:16 +08:00  2 会了这个算法能保证你 35 不被裁吗? | 
|      87nznd      2020-08-20 14:09:33 +08:00 @phpfpm #77 我说 python 这个大数运算库的 c 实现... 好难懂... 周末找个大块时间啃一下 这个题目挺简单 感觉是 leetcode easy 难度 | 
|      89fengmumu      2020-08-20 14:19:42 +08:00 菜鸡表示看了楼主的代码,嗯,够精减,话说,不明白楼主的意思,首先是完成你给定的需求:俩数相加,都没有符号 /没有小数点 /字符串表示 返回和 /用字符串表示 ,这个不过分,但是又看到有一堆的需求,不能 reverse, 不能强转 number 之类的,转 number 什么的,大数就 gg,这个你们搞个单元测试给跑一下,不过就挂我理解,至于什么 reverse 什么的,我理解就是 你是想让面试者高效+准确+优雅的完成这个东西,在已经实现了的基础上,用 for 循环的,垃圾不会用 while,倒着加的后面反转的,垃圾,代码过长的垃圾,写的时间长的垃圾,不知道我理解的对不对,而且弱弱猜一下,楼主没有给面试人引导+优化代码的时间吧 | 
|  |      90newmlp      2020-08-20 14:22:40 +08:00 是的 | 
|  |      91TrickWu      2020-08-20 14:24:59 +08:00 话说你 append 的这段 script 写的能正确输出么? | 
|      93followsin      2020-08-20 14:26:55 +08:00  7 EcmaScript 写错的人抱怨人家 reverse 拼错,😄 | 
|  |      94uasier      2020-08-20 14:28:47 +08:00 这题我写过,然后一看我写了 63L,对不起,是我不配。 | 
|  |      95XisucksYi      2020-08-20 14:31:01 +08:00 @jlak0106 所以說, 這種所謂的算法題無非就是有沒有 Google 過, Google 過誰不知道呢? 根本看不出一個人解決問題的能力. 我就碰到一個很好的面試, 直接出一個業務題, 可以用任何工具, 只要能完成任務就行. | 
|  |      97johnsona      2020-08-20 14:39:40 +08:00 前几天才在 leetcode 上做过这题,题主科班的?从没做过觉得自己多久能做完,会不会遗漏 | 
|  |      98sunziren      2020-08-20 14:42:19 +08:00 function funAdd(a,b){ math.config({number: 'BigNumber'}); return math.evaluate(a + "+" + b); } function funSub(a,b){ math.config({number: 'BigNumber'}); return math.evaluate(a + "-" + b); } |