我正在创建一种方法来了解字符串中有多少次“ RAV”。 我的程序可以运行,但是当字符串包含+10.000个字符时,它应该更快。
首先,我使用String,然后使用StringBuilder,它速度更快,但还不够。
public class E{
private static int replace(String cad){
StringBuilder sb = new StringBuilder(cad);
int cont = 0;
while (sb.indexOf("RAV") > -1 && cont < 50000) {
sb.replace(sb.indexOf("RAV"), sb.indexOf("RAV") + 3, "");
cont++;
}
return cont;
}
public static void main(String[] args) {
String[] arr = new String[]{"RARAVV", "VAR", "RAVV"};
for (int i = 0; i < arr.length; i++) {
System.out.println(replace(arr[i]));
}
}
}
预期输出为
2
0
1
答案 0 :(得分:2)
private static int replace(String cad) {
int originalLength = cad.length();
for (;;) {
String cad2 = cad.replace("RAV", "");
if (cad2.length() == cad.length()) {
break;
}
cad = cad2;
}
return (originalLength - cad.length()) / "RAV".length();
}
首先将indexOf
放入变量中,使其使用3次。
String.replace
可以进行多次替换。表达式的还原则具有不同的顺序,但是对于“ RAV”而言,不会产生不同的结果。
在上面,您可以测试cad2 == cad
的替换结果,但某些样式检查器将首选等于。长度相等就足够了。
当然,替换的数量是长度减少/ 3。
实际测量结果显示String.replace(String, String)
缓慢:
private static int replace(String cad) {
// Could try to shorten string: cad = cad.replaceAll("[^RAV]+", "e");
StringBuilder sb = new StringBuilder(cad);
int pos0 = 0;
for (;;) {
int pos = sb.indexOf("RAV", pos0);
if (pos == -1) {
break;
}
sb.delete(pos, pos + 3);
// Continue searching 2 chars before.
pos0 = Math.max(0, pos - 2); // RA[RAV]V
}
return (cad.length() - sb.length()) / 3;
}
感谢使用@GPI进行基准测试。
答案 1 :(得分:1)
首先我使用String,然后使用StringBuilder,它速度更快
确定吗?您使用了哪些测试用例?
为此:
RAVRAVRAVRAVRAVRAVRAVRAVRAVRAV
您认为StringBuilder
比String
快吗?
考虑这种方法:
public static int replace(String cad, String pattern){
String str = cad;
do {
str = str.replace(pattern, "");
} while (str.contains(pattern));
return (cad.length() - str.length()) / pattern.length();
}
在像上述replace()
这样的测试用例中,对于大多数随机测试用例,该版本的String
肯定比您快快,因为它可以提供1次迭代1次替换,不使用任何计数器。
当您处理以下情况时,StringBuilder
会更高效,更快:
RARARARARARARARARARAVVVVVVVVVV
答案 2 :(得分:1)
这是我对线性算法的看法。不是最通用或最漂亮的代码,而是它说明了这个想法。 对该字符串仅进行一次扫描,我们不会向后或向前看,这会在字符串长度上产生线性影响。
对于更长的字符串,这应该比基于“替换”的算法快得多。
public class Main {
private static class StateFrame {
int matched;
StateFrame previous;
}
private static int count(String cad) {
StateFrame state = new StateFrame();
final int len = cad.length();
int result = 0;
for (int i = 0; i < len; i++) {
final char ch = cad.charAt(i);
if (ch == 'R') {
if (state.matched == 0) {
state.matched = 1;
} else {
StateFrame next = new StateFrame();
next.previous = state;
state = next;
state.matched = 1;
}
} else if (ch == 'A') {
if (state.matched == 1) {
state.matched = 2;
} else {
state.previous = null;
state.matched = 0;
}
} else if (ch == 'V') {
if (state.matched == 2) {
result++;
if (state.previous == null) {
state.matched = 0;
} else {
state = state.previous;
}
} else {
state.previous = null;
state.matched = 0;
}
} else {
state.previous = null;
state.matched = 0;
}
}
return result;
}
public static void main(String[] args) {
String[] arr = new String[] { "RARAVV", "VAR", "RAVV", "RRAVRXXXAV", "RARRAVAVV", "RRAVARAVV", "RRARAVVARAVV" };
for (String anArr : arr) {
System.out.printf("%s %d%n", anArr, count(anArr));
}
}
}
输出为
RARAVV 2
VAR 0
RAVV 1
RRAVRXXXAV 1
RARRAVAVV 3
RRAVARAVV 3
RRARAVVARAVV 4
答案 3 :(得分:0)
如果您使用Title Status
title2 fail
进行此操作,将会更快。
recursion