领导在公司厕所偷拍同事拉屎,帽子叔叔看了好几天拉屎撒尿都要吐了。。
刚刷到一个离谱的新闻:公司领导居然在厕所装盒子偷拍同事上厕所,结果被发现报警,现在人被拘了。警察看录像都快吐了,同事们更是心理阴影一大片。
从程序员的角度看,这事真是“技术用错了地方”。DIY点子不少人有,但用在这种变态场景就彻底废了。信息安全里讲的核心就是“权限与边界”,厕所是最私密的空间,他却直接踩雷,还把整个团队的信任彻底清空。
网友有的说这是“重口味偷窥”,有的调侃“把裙底党都衬托得高尚”。但我觉得,笑归笑,影响却很严重。尤其对女同事,可能留下长期的心理创伤。
在职场,本来我们要面对的已经是代码Bug、系统崩溃这些问题,现在还得担心身边的领导是否变态,真是离谱。
最后我想说,技术本身是中性的,关键看人怎么用。希望这种人渣早点被清除出职场环境,让大家能安心工作。【备注:文末可领最新资料】
面试题:编辑距离
昨天晚上十一点多,在公司楼下吹风等外卖,脑子里还在想一个小坑,嗯…就是“编辑距离”那个玩意儿。别被名字吓到,它其实就是算两段字符串有多“费劲”才能互相改成一样,改法只有三种:插入一个字符、删掉一个、把一个换成另一个,每步都算一步代价,对吧。
为啥要关心编辑距离
你搜错别字、做拼写纠正、看日志里一堆近似的接口名(哦对是 API),都离不开它。比如把“kitten”改成“sitting”,最少要几步?这个数字就叫编辑距离,数字越小,越像。
定义先落地
设两个串 a、b。我们关心 a 的前 i 个字符和 b 的前 j 个字符的最小代价,记成 dp[i][j]。有点像爬格子:往右是插入、往下是删除、斜着是替换。边界也好理解,任何东西变空串只能一直删,反过来变成非空只能一直插。
动态规划的脑回路
那个…核心转移就三条路,选便宜的走:
删:dp[i-1][j] + 1 插:dp[i][j-1] + 1 换:dp[i-1][j-1] + (a[i-1] != b[j-1] ? 1 : 0) 看着像背口诀,其实就是问“最后一步怎么来的”。最后一步如果是删,那前面状态就少了一个字符;如果是插,那另一边少一个;如果最后两个字符本来就相等,走斜对角还能白嫖不加费。
defedit_distance(a: str, b: str) -> int:
# 小优化:谁短谁当列,省点内存
if len(a) < len(b):
a, b = b, a
m, n = len(a), len(b)
# dp[j] 表示上一行 dp[i-1][j];cur[j] 表示当前行 dp[i][j]
prev = list(range(n + 1))
for i in range(1, m + 1):
cur = [i] + [0] * n
ai = a[i - 1]
for j in range(1, n + 1):
cost = 0if ai == b[j - 1] else1
delete_ = prev[j] + 1# 从 dp[i-1][j] 删除 ai
insert_ = cur[j - 1] + 1# 从 dp[i][j-1] 插入 b[j-1]
replace_ = prev[j - 1] + cost # 从 dp[i-1][j-1] 替换/保持
cur[j] = min(delete_, insert_, replace_)
prev = cur
return prev[-1]
# 小测一下
if __name__ == "__main__":
print(edit_distance("kitten", "sitting")) # 3
print(edit_distance("", "abc")) # 3
print(edit_distance("abc", "abc")) # 0
时间是 O(mn),m、n 就是两个串的长度;空间这版是 O(min(m, n)),因为只留两行。要是你非得看全局路径,比如要高亮“哪儿改了”,那就别偷懒省内存了,老老实实开二维表,这样能反走一遍把操作步骤捞出来。还有一个细节哈,替换那步只有在最后字符不等的时候才加 1,相等就继承对角线的值,这点漏了会多算一步,昨天我们组那个小李就被这个坑了半小时,唉。
短字符串、容错匹配、自动纠错,很合适;但字符串一长到十几二十万,直接跑就吃不消了,这时候可以考虑限制距离上限(超过就提前停),或者分块、筛选候选再算精确值,别一上来就全量怼,服务器会哭。对了,中文分词场景要注意“字符”不等于“字节”,别拿 UTF-8 的切片去跑,那个…会裂开。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领