最近面试,按说候选人背景也都不错吧。
我们对算法要求没那么高,业务代码为主。
因此对于各种语言的候选人,我基本都会问一道长整数加法的问题。
俩数相加,都没有符号 /没有小数点 /字符串表示 返回和 /用字符串表示
这题难吗?
考察的知识点点挺广的:
字符串 /数组操作,循环控制,流程逻辑,边界条件等等。
这也基本上是编程的时候经常能遇到的问题。
但是我遇到的面试者写的千奇百怪的都有:
idx ** 10
等等吧
所以如果你遇到这个题,如何优雅的写一个 a+b?
稍后我写一个我自己花了一小点时间写的答案,八行,没有很过分的压缩代码 我的代码大概长这样:
function add(a, b) { let ... some magic { cast something cast other } return ... }
正经逻辑三四行写完,晚一些我贴条的方式公布我的答案。
如果要你写,你写啥?
1 islxyqwe 2020-08-20 11:07:07 +08:00 ![]() const add = (a,b)=>(BigInt(a) + BigInt(b)).toString() |
3 march1993 2020-08-20 11:08:45 +08:00 via iPhone 都字符串了 那就按字符串按位拼呗… |
![]() | 4 luckyrayyy 2020-08-20 11:10:00 +08:00 ![]() 我应该就是嗦嗦那种了。循环,字符取一位,转成 int,相加,记录进位,剩余的转回 str 加到结果上。 |
5 Jooooooooo 2020-08-20 11:11:57 +08:00 我理解写 a+b 如果是 string 就是考察最基本的代码能力 如果是 int 那考察思考全面性 (溢出怎么办? |
![]() | 6 dartabe 2020-08-20 11:13:16 +08:00 我咋看好多答案都用的 bigint |
7 phpfpm OP @Jooooooooo 溢出就 try-catch 一下吧,前置判断没啥意思了 @dartabe big int 用了我考啥。。。我也是反复强调不能用(当然绝大多数面试者不知道 hhh ) 主贴写的时候写漏了。 @march1993 @luckyrayyy 真的写一下估计会漏一些情况(比如最后的进位) |
8 hytex 2020-08-20 11:18:39 +08:00 怎么感觉是字符串相加的那个题… 按位取余多的进 1,然后叠加就行了啊… |
10 lijialong1313 2020-08-20 11:19:54 +08:00 字符串 /数组,反转处理不好吗…… 而且不能转 number 的话,难不成是两个字符串加起来之后减去对应的值?( C 语言) |
11 DL9412 2020-08-20 11:21:29 +08:00 这不是上周的每日打卡题么,模拟竖式就完事了 |
12 phpfpm OP @lijialong1313 c 处理 atoi 也确实可以这么干 主要是反转吧必要性没那么大 太多人只会正着写 for,不会反着写 for,不会写 while ; 或者你要用 map-reduce 之类的方法把字符串先 reverse 我还能忍 @hytex 话是这么说,欢迎提供代码~ 能贴条的时候我补充我的版本。 |
14 hytex 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(); } |
15 lijialong1313 2020-08-20 11:26:59 +08:00 ![]() @phpfpm 主要是不反转的话,对于最左的进位就需要额外的一次移动所有字符串操作( c 语言),我做 oj 遇到这种都是习惯反着处理。 |
![]() | 17 yhxx 2020-08-20 11:28:54 +08:00 import { BigNumber } from 'big-number'; return BigNumber(a).add(b); (手动滑稽 |
18 phpfpm OP |
19 lijialong1313 2020-08-20 11:31:36 +08:00 @phpfpm 那这样的话,这玩意儿应该满地都是大数加法算法了吧( C 语言) |
23 phpfpm OP @lijialong1313 满地都是大数加法算法了吧没跟上。 我们不招 c 的,不过有年头比较长嵌入式北京的我会随口问一句 C 的 VLA 形如 ``` struct foo { char bar; int[0] baz; }; ``` 这个 trick 了 (我也只会这个了 hhh |
![]() | 24 no1xsyzy 2020-08-20 11:39:36 +08:00 |
25 islxyqwe 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) |
![]() | 26 ytmsdy 2020-08-20 11:41:24 +08:00 via iPhone 我记得当年刚刚开始玩 acm 的时候,zoj 上的第一道题就是大数 a+b 。那时候花了快 3 天才搞完! 现在想想,从最后一位开始模拟手工计算的过程就好了! |
![]() | 27 cyrbuzz 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')) ``` |
![]() | 28 no1xsyzy 2020-08-20 11:42:25 +08:00 |
30 phpfpm 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 } ``` 希望回复能好看点。。。。 |
![]() | 31 no1xsyzy 2020-08-20 11:55:27 +08:00 @phpfpm #30 APPEND 需要自己选择语法是 Default 还是 Markdown 这个用 res.length 来记录是否有进位有点奇技淫巧了 |
![]() | 33 no1xsyzy 2020-08-20 11:58:27 +08:00 @phpfpm #30 也不能说奇技淫巧,就是在各种地方找到能放信息的地方 还是 add(x,y) = x&y<<1 + x|y 更奇技淫巧…… |
![]() | 34 no1xsyzy 2020-08-20 11:59:45 +08:00 @banishee #32 唯一处理数组的地方是取 a[] 和 b[],JS 下溢出是 undefined, ~~x 之后就是 0,这点上无法替换为 +x,因为 +x 会变成 NaN |
![]() | 35 murmur 2020-08-20 12:00:21 +08:00 有大整数类为啥要自己写,你能保证写出来的过的单元测试比库更多么 |
![]() | 36 wutiantong 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; } |
37 lijialong1313 2020-08-20 12:02:52 +08:00 @phpfpm 我写了一个 c 语言的: https://paste.ubuntu.com/p/YjF5DZqXnR/ |
![]() | 38 YuTengjing 2020-08-20 12:09:48 +08:00 via Android 这道题很常见啊,不会做说明没怎么准备面试算法 |
![]() | 39 XiaoxiaoPu 2020-08-20 12:12:04 +08:00 确实不难吧,我大一就能做高精度浮点数的加减乘除、三角函数、指数、对数函数了,虽然效率一般。 |
![]() | 40 mazyi PRO 面试笔试做不出长整数加法的是不是 coding 能力就基本当没有了? |
![]() | 41 talen666 2020-08-20 12:26:09 +08:00 两个字符串相加??做业务跟这个关系不大。。 |
![]() | 43 shuigui 2020-08-20 12:28:55 +08:00 是的,这个是基本逻辑能力 |
![]() | 44 shm7 2020-08-20 12:33:12 +08:00 就是基本逻辑吧,不要随便问个题目想看看你脑子转不转,就上纲上线。 |
![]() | 45 shm7 2020-08-20 12:33:59 +08:00 ![]() 我觉得你说的这个输入 2 字符串算结果输出字符串都做不好,那真是没有什么编程能力了。 |
![]() | 46 XisucksYi 2020-08-20 12:34:47 +08:00 ![]() 知道有什意? 言只是工具, 可以完成任就行, 不能, 不能用 built-in, 我想下弄有什意. 我得你和面者聊意的西是你被打死. |
47 sampeng 2020-08-20 12:41:19 +08:00 via iPhone ![]() 你这叫没过分压缩代码?写成一行才算? |
48 672795574 2020-08-20 12:47:45 +08:00 |
![]() | 49 peapods 2020-08-20 12:48:51 +08:00 via Android ![]() 很多面试真的就是玩弄一些奇技淫巧,用一个随便一搜就能解决的问题来刁难面试者,每天被狗屁项目经理(领导)逼着搬砖写各种 bug 还不够么。问题来了,一个茴香豆有几种写法? |
50 sampeng 2020-08-20 12:48:54 +08:00 via iPhone @XisucksYi 那如何在面试中判断一个人的逻辑能力呢?当然我没过分到要用笔试。比如我最喜欢问的。用 a 去分割字段 b 。不许用内置函数。是不是比楼主这种简单 100 倍。答得上来的成功率不超过 20%用两种以上思路的…em 。二十个里面有一个吧 |
![]() | 51 ChenFanlin 2020-08-20 12:49:12 +08:00 |
![]() | 52 jmc891205 2020-08-20 12:49:20 +08:00 加法太 straightforward了,没什么好讨论的 乘法还可以 |
![]() | 53 hikarugo 2020-08-20 12:49:28 +08:00 还行吧,看什么时期,应届生是好题,社招见仁见智吧 |
54 phpfpm OP |
![]() | 57 czzhengkw 2020-08-20 12:53:09 +08:00 吓得我赶紧试着写了一下,还好,能写出来 |
58 sampeng 2020-08-20 12:55:21 +08:00 via iPhone @phpfpm 对啊…而且我都没说手写,说说思路就行…就是这么夸张…所以楼主简单的算法题过滤人完全没问题…感觉现在是用人市场,找工作的比招聘的多得多。所以择优选择一点毛病没有 |
59 phpfpm OP @ChenFanlin @jmc891205 @fyxtc 这个我校招社招都问过,区分度区别不大。 在学校瞎混的和社招写了几年代码事儿都忘光的都有。 简单题。。要是乘法的话估计一般来说没半个小时写不完,我面试时间一共才 45min,等不起,而且区分度更差。 本质上我这边招人还是要能自己 coding 的,再牛的人来该干活还是得干活。 @672795574 你的意思是这里也有产品混进来吧 懂你懂你。 |
![]() | 60 murmur 2020-08-20 12:57:01 +08:00 ![]() @reus 有滴滴为什么考驾照?因为不是什么时候都有滴滴,但是我什么时候都能搜到第三方库 而且我这岂止是滴滴,这滴滴还有个接单 10w 无事故的老司机,怎么说都是滴滴爽 如果类比的话,去的公司禁止使用源,不准使用外部网络和代码,所有算法自己手写,可能有这个实际需求 |
![]() | 61 dartabe 2020-08-20 12:58:28 +08:00 确实是 leetcode 里面 easy 题里面都算简单的 |
62 phpfpm OP |
63 672795574 2020-08-20 13:07:49 +08:00 我倒是挺好奇,会这题的人,有觉得楼主面试问这题没有意义么 |
64 nznd 2020-08-20 13:08:27 +08:00 常用 python 的我 第一反应想出来的就是基础的模拟按位加法,然后一想 python 无限长度 int 都可以加,就去看了下实现 https://github.com/python/cpython/blob/2d264235f6e066611b412f7c2e1603866e0f7f1b/Modules/_decimal/_decimal.c 现在在怀疑人生 |
65 phpfpm OP |
66 phpfpm OP @
|