领导在公司厕所偷拍同事拉屎,警察叔叔看了好几天拉屎撒尿都要吐了。。
刚刷到个离谱的新闻:某公司领导居然在厕所DIY小盒子,用手机偷拍同事上厕所,结果装置掉出来被发现,报警后一堆警察被迫看了几天屎尿视频,女同事抑郁、男同事无语,这位领导也被拘留。
第一反应是——他要是把搞偷拍的心思放在写代码上,说不定早升CTO了。在我们行业,隐私就是底线,连一条日志打印多点用户信息都要被骂,这哥们直接把摄像头对准厕所,离谱到没边。
网友们调侃说这种偷拍方式甚至让“偷拍裙底”显得高大上了,但我觉得再怎么黑色幽默,本质还是对同事隐私的践踏。换个角度想,职场讲究信任,就像我们做团队开发,代码库里全是互相信任的commit,他这一搞,相当于在代码里偷偷埋木马,迟早被抓。
算法题:比较版本号对象
昨天晚上十一点多,我在公司楼下吹风,手机里有人给我发了个包,说你看下这个版本到底新不新,“1.0.10”和“1.0.2”,我当时眼睛一眯,嘿,这不就是比较版本号吗。别笑,真有坑。看着像字符串,其实比较规则跟数字更像,但又不能直接把整串当大整数塞进去,容易溢出、还慢。
版本号一般长这样:“主.次.修复”,比如 2.4.1。比较的时候,是从左到右,一段一段比。每段是数字,前导零要忽略,比如 “007” 就是 7。长度不一样怎么办?短的那边缺的段视为 0,比如 “1.2” 等于 “1.2.0”。只要某一段大了,就不用继续了。
最稳妥的做法是把两边都按 . 切开,一路同步走。每段别急着 Integer.parseInt,万一人家一段有几十位就爆了。我们可以先把每段的前导零去掉,再比较长度;长度大的数值就大。长度一样再按字典序比较(这时候每位都是 0-9,字典序和数值序一致)。如果某一边这一段是空串,等价 0。
第一,连续点比如 “1..0”,中间那段其实就是空,按 0 处理就好。第二,尾部很多零不要当成更大:“1.0.0.0”和“1”是相等的。第三,别在循环里频繁构造大对象,简单点用指针走字符串也行,但 Java 里把段取出来再比,已经够快够清晰。
publicclassVersionCompare{
publicstaticintcompareVersion(String v1, String v2){
String[] a = v1.split("\\.", -1); // -1 保留空段
String[] b = v2.split("\\.", -1);
int n = Math.max(a.length, b.length);
for (int i = 0; i < n; i++) {
String s1 = i < a.length ? a[i] : "";
String s2 = i < b.length ? b[i] : "";
int r = compareNumString(s1, s2);
if (r != 0) return r;
}
return0;
}
// 比较只包含数字的两段,允许空串和前导零
privatestaticintcompareNumString(String x, String y){
int i = skipZeros(x), j = skipZeros(y);
int len1 = x.length() - i;
int len2 = y.length() - j;
if (len1 != len2) return len1 > len2 ? 1 : -1;
// 长度相等,逐字符比较
for (int k = 0; k < len1; k++) {
char c1 = x.charAt(i + k), c2 = y.charAt(j + k);
if (c1 != c2) return c1 > c2 ? 1 : -1;
}
return0; // 完全一样(都可能是空或“000”)
}
privatestaticintskipZeros(String s){
int p = 0;
while (p < s.length() && s.charAt(p) == '0') p++;
return p;
}
// 小测一下
publicstaticvoidmain(String[] args){
System.out.println(compareVersion("1.0.10", "1.0.2")); // 1
System.out.println(compareVersion("1.01", "1.001")); // 0
System.out.println(compareVersion("1.0.0.0", "1")); // 0
System.out.println(compareVersion("2..3", "2.0.3")); // 0
System.out.println(compareVersion("000", "0")); // 0
System.out.println(compareVersion("3.9", "3.10")); // -1
}
}
时间复杂度基本就是把两个字符串扫一遍,O(n+m);空间上,split 会多点临时数组,但代价可接受。如果你特别在意 GC,可以写成双指针不切割版本的流式比较:两个指针遇到点号就停,按上面规则比一段,完了指针往后挪一格继续,效果一样还更省内存。哦对了,如果团队的版本号还带后缀 “-alpha”“-rc1” 这种,就得先定义清楚优先级规则;纯数字段世界里,上面这套就够用了。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html