我需要检查一个字符串中不同字符的数量,其长度可以长达20,000,总测试用例数<= 10,000。我是通过替换字符串的其他字符然后检查其长度来完成的,如下面的代码所示:
int no7=myString.replaceAll("[^7]","").length();
int no0_3=myString.replaceAll("[^0-3]","").length();
int no5_6=myString.replaceAll("[^56]","").length();
我想知道replaceAll方法是如何工作的,如果我在一个循环中进行计数检查字符串的每个字符,它是否会更快。提前谢谢。
答案 0 :(得分:2)
首先,您可以在字符类之后添加+
(例如[^7]+
),以便更快地完成替换。这将取代连续运行的不需要的字符,而不是一次只替换一个。根据您的输入字符串,这可能会显着提升您的性能。
但在你的情况下,我不会真正替换任何东西并检查长度。你想要的是七人制的数量,0到3之间的数字以及五和六的数量。所以只需编写一个循环来检查这些:
int no7 = 0, no0_3 = 0, no5_6 = 0;
for (int i = 0; i < myString.length(); i++) {
char c = myString.charAt(i);
if (c == '7') no7++;
if (c >= '0' && c <= '3') no0_3++;
if (c == '5' || c == '6') no5_6++;
}
这样会更快,因为你不必构造三个单独的字符串来检查它们的长度并再次抛弃它们,你还可以节省正则表达式构造,解析和运行时。因此,对每个字符进行简单的迭代(这正是正则表达式必须做的事情)因此,如果不是更多的话,最多只能将的时间减少到原始运行时的三分之一。
答案 1 :(得分:0)
replaceAll在内部构造Pattern,然后在提供的字符串上调用Matcher方法。模式编译需要一些时间,所以如果您经常这样做 - 那么在代码中使用预编译模式作为静态最终字段是最好的方法。
答案 2 :(得分:0)
我想知道replaceAll方法是如何工作的
我认为API documentation已经明确提到它了:
“调用str.replaceAll(regex,repl)形式的此方法会产生与表达式
完全相同的结果Pattern.compile(正则表达式).matcher(STR).replaceAll(REPL)“
如果我在单个循环中进行计数检查字符串的每个字符
,它是否会更快
我怀疑,编译的正则表达式几乎总是比手动字符检查更快。如果字符数很小,它可能会更快,但它也取决于你将如何构建结果字符串(请记住java字符串是不可变的)。