Python技术迷

今天给一个老员工降薪20%他本来月薪15000,降完剩12000。我本以为他会很生气,甚至找我吵一架,结果他沉默了几分钟

这老板还挺会给自己加戏。

37岁的老员工,干了5年,工资从一万五砍到一万二。人家房贷车贷压着,一个月固定开销都快小一万了。老板本来还等着对方拍桌子、吵一架,结果人家愣了几分钟,只回了句行,就走了。

这才是最扎心的地方。

Image

成年人的崩溃哪有那么多大喊大叫。真到这岁数,上有生活,下有账单,连生气都得算成本。你以为他是没脾气?他可能只是在想,房贷怎么办,车贷怎么办,下个月简历投哪儿。

后面老板又让财务多补了点,像是给自己心里找个台阶。可那员工看着工资条,嘴动了动又忍住了,这画面真挺职场的。

有时候人不吵,不是服了,是已经开始在心里收拾东西了。

今日算法题

a1b2c3 这种字符串,最后要变成 anumberbnumbercnumber。

这题看着太小了,小到不少人第一反应就是:

s = s.replace('1', 'number')

然后开始把 0 到 9 全写一遍。

这地方我一般不太建议这么干。不是不能过,是代码一眼看过去就不像在解题,像在补窟窿。数字有 10 个,你写 10 次 replace,题目稍微一改,比如把所有大写字母也替换掉,这段代码基本就废了。

这题真正要抓的点只有一个:从左到右扫字符串,遇到数字就追加 number,不是数字就原样追加。

Python 里字符串是不可变对象,别想着在原字符串上改。你每拼一次,其实都可能创建一个新字符串。数据小的时候没感觉,数据稍微一大,这种写法就开始不老实了。

比如这种:

ans = ""
for ch in s:
if ch.isdigit():
        ans += "number"
else:
        ans += ch

能跑,但我不喜欢。竞赛题里有时候输入规模卡得不明显,平时写脚本处理日志、批量清洗字段,这种习惯迟早会让你吃一次慢查询一样的亏。

我更习惯先放到列表里,最后一次性 join。

import sys


defreplace_digit(text: str) -> str:
    pieces = []

for ch in text:
if'0' <= ch <= '9':
            pieces.append("number")
else:
            pieces.append(ch)

return''.join(pieces)


defmain():
    line = sys.stdin.readline().rstrip('\n')
    print(replace_digit(line))


if __name__ == "__main__":
    main()

这里我没用 ch.isdigit(),不是它不能用,而是这题通常说的是字符串里的数字字符,也就是 '0' 到 '9'。isdigit() 能识别的东西更宽一点,真放到线上处理脏数据时,有些全角数字、特殊数字字符也可能被它认进去。

算法题里按题意来,别自作聪明。

走一遍例子:

输入:
a5b

扫描:
a  -> 原样放进去
5  -> 替换成 number
b  -> 原样放进去

输出:
anumberb

再看一个边界:

输入:
123

输出:
numbernumbernumber

没有字母也没关系,全是数字就全替换。 如果没有数字:

输入:
abc

输出:
abc

原样输出。

这题的时间复杂度是 O(n),每个字符只看一次。空间复杂度也是 O(n),因为替换后的字符串肯定要重新生成,特别是一个数字会变成 6 个字符,不可能原地省掉。

这类题别想复杂了。它考的不是高级算法,就是字符串处理的基本手感:别重复 replace,别循环里硬拼大字符串,别把题意外的字符也顺手处理了。

代码短一点,判断准一点,就够了。