0

我需要检查一个字符串中不同字符的数量,其长度可以长达 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 方法是如何工作的,以及如果我在一个循环中检查字符串的每个字符是否会更快。提前致谢。

4

3 回答 3

2

首先,您可以通过+在字符类(例如[^7]+)之后添加一个来加快替换速度。这将替换连续运行的不需要的字符,而不是一次只替换一个。根据您的输入字符串,这可能会显着提升性能。

但在你的情况下,我不会真正更换任何东西并检查长度。你想要的是 7 的数量,0 到 3 之间的位数以及 5 和 6 的数量。所以只需编写一个循环来检查这些:

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++;
}

这会更快,因为您不必构造三个单独的字符串来检查它们的长度并再次丢弃它们,并且您还可以节省正则表达式的构造、解析和运行时。因此,对每个字符的简单迭代(这是正则表达式无论如何都必须做的)因此将您的时间最多减少到原始运行时间的三分之一,如果不是更多的话。

于 2012-10-07T14:29:32.870 回答
0

replaceAll 在内部构造 Pattern,然后在提供的字符串上调用 Matcher 方法。模式的编译需要一些时间,所以如果你经常这样做——那么在你的代码中使用预编译的模式作为静态最终字段是最好的方法。

于 2012-10-07T14:29:19.687 回答
0

我想知道 replaceAll 方法是如何工作的

我认为API 文档已经清楚地提到了它:

“调用这种形式为 str.replaceAll(regex, repl) 的方法会产生与表达式完全相同的结果

Pattern.compile(regex).matcher(str).replaceAll(repl)"

以及如果我在一个循环中检查字符串的每个字符是否会更快

I doubt that, compiled regex is almost always faster than manual character checking. It may be faster if the number of characters is small, but it also depends on how you will build the resulting string (remember that java strings are immutable).

于 2012-10-07T14:31:15.220 回答