另一种选择是:
- 从字符串中删除您不关心的所有字符(标点符号、空格)
- 把它变成小写
- 对字符串进行排序
- 与参考字符串比较(带
.equals
)
我怀疑你的方式更快。
编辑:
由于@nibot 不同意我的建议,而且我不是一个在没有证据的情况下来回争论的人,这里有三个解决方案。
它们的实现都非常相似:
- 将行转换为小写
- 忽略非字母字符
- ?
- 检查 3. 的结果与第一行的结果相匹配
这 ?部分是以下之一:
- 进行
HashMap
字符计数
- 对字符进行排序
- 制作一个 26-int 数组(最终的哈希表解决方案,但仅适用于拉丁字母)
我用这个运行它们:
public static void time(String name, int repetitions, Function function,
int expectedResult) throws Exception {
long total = 0;
for (int i = 0; i < repetitions; i++) {
System.gc();
long start = System.currentTimeMillis();
int result = function.call();
long end = System.currentTimeMillis();
if (result != expectedResult) {
System.out.println("Oops, " + name + " is broken");
return;
}
total += end - start;
}
System.out.println("Executution of " + name + " took "
+ (total / repetitions) + " ms on average");
}
我的文件与 OP 发布的文件相似,但长度明显更长,从末尾开始有大约 20 行的非字谜,以确保算法都能正常工作。
我一直得到这样的结果:
Execution of testWithHashMap took 158 ms on average
Execution of testWithSorting took 76 ms on average
Execution of testWithArray took 56 ms on average
如果满足以下HashMap
条件,则可以显着改善:
但是,这些不在标准库中,所以我忽略了它们(就像大多数使用 Java 的程序员一样)。
这个故事的寓意是,大 O 并不是一切。您需要考虑n的开销和大小。在这种情况下,n相当小,并且 a 的开销HashMap
很大。对于更长的线路,这可能会改变,但不幸的是,我不想弄清楚盈亏平衡点在哪里。
如果您仍然不相信我,请考虑 GCC 在其 C++ 标准库中的某些情况下使用插入排序。