和同事嬉戏打闹,一不小心亲了他一口,现在应该怎么收场?
刚看到个贴子,说有网友跟同事打闹打着打着,一激动亲上去了,现在整个人都尴尬到原地蒸发。
我觉得这事吧,关键不是“亲了没”,而是你们平时的关系到底是什么程度。如果只是普通同事,那这一下确实容易惹麻烦,尤其职场这种地方,八卦传播速度比WiFi还快。
最稳妥的处理方式就是主动、轻描淡写地解释一下,类似“刚才闹过了,不好意思哈”,给个台阶,也给彼此边界划清。
如果对方也大方,那这事就过去了;如果对方明显不自在,那你之后更得注意保持距离,别再给别人造成压力。
坦诚一点,稳住心态,不逃不凶,这事还是能圆回来的。毕竟,职场风大,别让一时的失误影响了正常工作。【备注:文末可领最新资料】
面试题:基本计算器
说“基本计算器”这个题啊,其实就是面试里那种:给你一串字符串形式的算式,让你自己写代码算结果。看着像小学生口算,细节一多,很多人就翻车了 😂
下面我们就用 Python 写一个支持 + - () 的“基本计算器”,像力扣 224 那种,不搞 * /,先把核心思路吃透。
题目大概长这样(伪版):
输入:一个只包含
数字(可能是多位数) 加号 +减号 -括号 ()以及若干空格 的字符串,比如: "1 + (2 - 3) + 4"输出:这个算式计算出来的整数结果,比如上面那个就是
4
没有乘除,没有小数,没有负号在数字前那种奇怪形式,一切都很“朴素”,但括号一来,大家就容易写成一坨 if-else 地狱。
模拟你手算的过程
你脑子里一般是这么算的:
从左往右扫
遇到数字就往后拼:看到
1、2、3组合成123遇到
+或-,就把前面攒好的数字按之前的符号加到当前结果上,然后更新“当前符号”括号怎么办?
遇到 (,你会“暂存”当前算到哪了,等括号里面算完再合回来遇到 ),就先把括号里的小结果算出来,再带上进入括号前的符号,和外面的结果合并
翻译成代码友好的模型,就是:
一个当前结果 res,表示“当前这一层括号里的和”一个当前的符号 sign,只有两种:+1或-1一个当前正在读的数字 num再加一个栈 stack,专门用来“保存遇到左括号时的现场”
每一步怎么干?
遇到数字:
num = num * 10 + int(ch)(处理多位数)遇到
+/-:先把之前的 num刷进res:res += sign * num然后更新 sign为当前符号再把 num清零遇到
(:先把当前的 res和sign依次丢进栈里保存然后重置: res = 0,sign = 1,相当于进了一个“新的小世界”遇到
):先和前面一样,把当前 num结清:res += sign * num然后从栈里弹出之前保存的:先是 prev_sign,再是prev_res新的 res = prev_res + prev_sign * res,也就是“外层结果 + 外层符号 ×(括号里的结果)”最后把 num清零空格:直接忽略
字符串扫完以后,别忘了把最后一个 num 也加进去一次(因为结尾可能是数字,不会再触发符号去结算它)。
直接给你一个可以过题的版本,函数签名跟力扣那题一致:
classSolution:
defcalculate(self, s: str) -> int:
stack = [] # 栈:保存进入每一层括号之前的 (res, sign)
res = 0# 当前这一层的结果
num = 0# 当前正在读取的数字
sign = 1# 当前符号,1 表示 + ,-1 表示 -
for ch in s:
if ch.isdigit():
# 处理多位数,比如 "123"
num = num * 10 + int(ch)
elif ch == '+'or ch == '-':
# 碰到运算符,先把前面的数字结算进 res
res += sign * num
num = 0
# 更新当前符号
sign = 1if ch == '+'else-1
elif ch == '(':
# 进新括号:先把当前状态压栈
stack.append(res)
stack.append(sign)
# 重置当前层
res = 0
sign = 1
elif ch == ')':
# 先把括号里的最后一个数字结算
res += sign * num
num = 0
# 恢复外层的 sign 和 res
prev_sign = stack.pop()
prev_res = stack.pop()
# 外层结果 + 外层符号 * 括号内结果
res = prev_res + prev_sign * res
else:
# 空格之类的直接跳过
continue
# 字符串扫完,还可能剩一个 num 没加
res += sign * num
return res
你可以自己测几个例子,比如:
"1 + 1"→ 2" 2-1 + 2 "→ 3"(1+(4+5+2)-3)+(6+8)"→ 23
拿这个函数跑一跑就能感受到逻辑还是很顺的。
再用一个例子走一遍流程
以 "1-(2-3)" 为例,大致是这样:
一开始: res = 0, sign = 1, stack = []读到 1:num = 1读到 -:结算:res = 0 + 1*1 = 1,sign = -1,num = 0读到 (:把外层状态压栈:stack = [1, -1],然后res = 0, sign = 1读到 2:num = 2读到 -:res = 0 + 1*2 = 2,sign = -1,num = 0读到 3:num = 3读到 ):先结算括号内:res = 2 + (-1)*3 = -1再从栈里弹出:prev_sign = -1, prev_res = 1外层结果:res = 1 + (-1)*(-1) = 2,刚好是1 - (2 - 3)的结果
这样走一遍你就会发现:其实就是“人脑算式”的程序化版本。
复杂度这块很简单:
时间复杂度: O(n),只扫一遍字符串空间复杂度: O(n),最坏情况括号层层嵌套,全靠栈保存状态
如果以后你要支持 */ 版本的“基本计算器 II / III”,核心变化就是:
多一个“栈处理乘除优先级”或者 写一套递归下降解析器
但今天这个只支持 + - () 的版本,先写熟练了,后面升级也就一层一层加细节。
你可以先把这段代码打到本地,随便造几组表达式玩一玩,有问题再喊我一起调。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领