最近面试,按说候选人背景也都不错吧。
我们对算法要求没那么高,业务代码为主。
因此对于各种语言的候选人,我基本都会问一道长整数加法的问题。
俩数相加,都没有符号 /没有小数点 /字符串表示 返回和 /用字符串表示
这题难吗?
考察的知识点点挺广的:
字符串 /数组操作,循环控制,流程逻辑,边界条件等等。
这也基本上是编程的时候经常能遇到的问题。
但是我遇到的面试者写的千奇百怪的都有:
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 5
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 2
我应该就是啰啰嗦嗦那种了。循环,字符取一位,转成 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 1
@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 2020-08-20 12:15:24 +08:00
面试笔试做不出长整数加法的是不是 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 1
我觉得你说的这个输入 2 字符串算结果输出字符串都做不好,那真是没有什么编程能力了。
|
46
XisucksYi 2020-08-20 12:34:47 +08:00 1
知道這個有什麼意義? 語言只是工具, 可以完成任務就行, 不能強轉, 不能用 built-in, 我想問下這樣弄有什麼意義.
我覺得你和面試者聊這種沒意義的東西是你會被打死. |
47
sampeng 2020-08-20 12:41:19 +08:00 via iPhone 1
你这叫没过分压缩代码?写成一行才算?
|
48
672795574 2020-08-20 12:47:45 +08:00
|
49
peapods 2020-08-20 12:48:51 +08:00 via Android 1
很多面试真的就是玩弄一些奇技淫巧,用一个随便一搜就能解决的问题来刁难面试者,每天被狗屁项目经理(领导)逼着搬砖写各种 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
fyxtc 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 3
@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 |
67
XisucksYi 2020-08-20 13:13:51 +08:00
我要是面試官的話, 我出冒泡排序題, 寫出來的我肯定過濾掉這種人的, 因為知道怎麼寫的肯定事先了解過冒泡排序, 說明他平時浪費時間搞這些算法, 我可不想跟這種書呆子做同事.
|
68
shilyx 2020-08-20 13:15:03 +08:00
直接面试求 100 的阶乘得了
|
69
672795574 2020-08-20 13:20:36 +08:00
@phpfpm DP 是个好题目,本身的框架就几行,看看对方怎么得出递推公式,有来有回交流一下,思路 /沟通都可以看出来。我被问得最多的也是 DP..
|
70
phpfpm OP |
71
phpfpm OP @672795574 等我结束这个阶段招聘之后我单独写一个 dp 的面试技巧(从面试官的角度)
本质上来说我(现在面试招聘的岗位)不需要算法大牛(业务属性相关),希望面试者具有聪明+思维严谨的属性。 当然如果是其他业务需求考察 dp 就更难了,比如剪枝优化等等,leatcode 偏难的题目的思路: 硬钢肯定超时,不优化的 dp 过不去几个点,优化到一定程度才能 AC 。 |
72
XisucksYi 2020-08-20 13:28:51 +08:00 3
|
74
crazycarry 2020-08-20 13:32:52 +08:00
看到你的回复了,真把自己当个菜?还面试官,,真当自己是个官了。是哪个大厂的?要是垃圾厂别笑死人了
|
75
tigren 2020-08-20 13:34:46 +08:00
我应该属于啰哩啰唆的那种的,遥记得第一次写的时候我写的是右边对齐,然后从左边开始一位位加,做完面试官表示很无语:虽然你这不算错,但是感觉这么别扭
|
76
CismonX 2020-08-20 13:42:33 +08:00 via iPhone
我大三的时候面字节跳动实习岗位的时候让我手写大数乘法,要求优于平方时间复杂度,然后我给他写了个 karatsuba 算法,他看了看不满意(可能写的不太对),然后我跟他说我还知道有个 toom-cook 算法,但是不会写。然后就没有然后了。。
|
78
XisucksYi 2020-08-20 13:43:31 +08:00
|
79
jlak0106 2020-08-20 13:44:01 +08:00
是挺垃圾的,大厂估计没这闲功夫在这发帖吧
|
80
wutiantong 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; } |
81
InkStone 2020-08-20 13:51:00 +08:00 1
我觉得你第二个贴条写的那个高精加挺烂的
评价代码好无非是两种标准,一种是清楚,一种是高效。拿代码长短去评价代码是否优秀,给人的感觉就像是既不做工程也不会底层 |
82
XisucksYi 2020-08-20 13:53:11 +08:00
@jlak0106 我不知道他是不是創業的小廠 CEO, 如果是的話, 他真的在浪費時間, 活該創業失敗. 我遇到很多創業的合夥人都是這樣, 一直皎潔這些沒意義的東西, 一副書生氣, 自己被算法噁心過還要噁心下面試的人, 又抱怨招不到人.
書生能做什麼大事呢? 書生輕議塚中人, 塚中笑爾書生氣罷了 |
84
jlak0106 2020-08-20 13:58:08 +08:00 2
@XisucksYi 我们组去年来了大神,不爱说话,天天在那看算法,还神经算法,让他自己都说不清楚,进来写个业务代码,bug 多的触发测试环境复盘。每个人都有自己的兴趣和钻研方向,不能你喜欢算法,别人不喜欢,写不出来就 coding 能力就基本当没有,楼主是人身攻击???自己怎么不去算法岗位去试试!!
|
85
Panic 2020-08-20 14:00:16 +08:00 2
会了这个算法能保证你 35 不被裁吗?
|
87
nznd 2020-08-20 14:09:33 +08:00
@phpfpm #77 我说 python 这个大数运算库的 c 实现... 好难懂... 周末找个大块时间啃一下 这个题目挺简单 感觉是 leetcode easy 难度
|
89
fengmumu 2020-08-20 14:19:42 +08:00
菜鸡表示看了楼主的代码,嗯,够精减,话说,不明白楼主的意思,首先是完成你给定的需求:俩数相加,都没有符号 /没有小数点 /字符串表示 返回和 /用字符串表示 ,这个不过分,但是又看到有一堆的需求,不能 reverse, 不能强转 number 之类的,转 number 什么的,大数就 gg,这个你们搞个单元测试给跑一下,不过就挂我理解,至于什么 reverse 什么的,我理解就是 你是想让面试者高效+准确+优雅的完成这个东西,在已经实现了的基础上,用 for 循环的,垃圾不会用 while,倒着加的后面反转的,垃圾,代码过长的垃圾,写的时间长的垃圾,不知道我理解的对不对,而且弱弱猜一下,楼主没有给面试人引导+优化代码的时间吧
|
90
newmlp 2020-08-20 14:22:40 +08:00
是的
|
91
TrickWu 2020-08-20 14:24:59 +08:00
话说你 append 的这段 script 写的能正确输出么?
|
93
followsin 2020-08-20 14:26:55 +08:00 7
EcmaScript 写错的人抱怨人家 reverse 拼错,😄
|
94
uasier 2020-08-20 14:28:47 +08:00
这题我写过,然后一看我写了 63L,对不起,是我不配。
|
95
XisucksYi 2020-08-20 14:31:01 +08:00
@jlak0106 所以說, 這種所謂的算法題無非就是有沒有 Google 過, Google 過誰不知道呢? 根本看不出一個人解決問題的能力.
我就碰到一個很好的面試, 直接出一個業務題, 可以用任何工具, 只要能完成任務就行. |
97
johnsona 2020-08-20 14:39:40 +08:00
前几天才在 leetcode 上做过这题,题主科班的?从没做过觉得自己多久能做完,会不会遗漏
|
98
sunziren 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); } |