Java 计算字符串中的逗号数,双引号之间的逗号除外
我有下面的函数来计算字符串中逗号(或任何其他字符)的数量,而不计算双引号中的逗号。我想知道是否有更好的方法来实现这一点,或者你是否能找到这个函数可能崩溃的情况Java 计算字符串中的逗号数,双引号之间的逗号除外,java,string,performance,counter,Java,String,Performance,Counter,我有下面的函数来计算字符串中逗号(或任何其他字符)的数量,而不计算双引号中的逗号。我想知道是否有更好的方法来实现这一点,或者你是否能找到这个函数可能崩溃的情况 public int countCharOfString(char c, String s) { int numberOfC = 0; boolean doubleQuotesFound = false; for(int i = 0; i < s.length(); i++){ if(s.ch
public int countCharOfString(char c, String s) {
int numberOfC = 0;
boolean doubleQuotesFound = false;
for(int i = 0; i < s.length(); i++){
if(s.charAt(i) == c && !doubleQuotesFound){
numberOfC++;
}else if(s.charAt(i) == c && doubleQuotesFound){
continue;
}else if(s.charAt(i) == '\"'){
doubleQuotesFound = !doubleQuotesFound;
}
}
return numberOfC;
}
public int countCharOfString(字符c,字符串s){
int numberOfC=0;
布尔值doubleQuotesFound=false;
对于(int i=0;i
谢谢你的建议
public static int countCharOfString(char c, String s)
{
int numberOfC = 0;
int innerC = 0;
boolean holdDoubleQuotes = false;
for(int i = 0; i < s.length(); i++)
{
char r = s.charAt(i);
if(i == s.length() - 1 && r != '\"')
{
numberOfC += innerC;
if(r == c) numberOfC++;
}
else if(r == c && !holdDoubleQuotes) numberOfC++;
else if(r == c && holdDoubleQuotes) innerC++;
else if(r == '\"' && holdDoubleQuotes)
{
holdDoubleQuotes = false;
innerC = 0;
}
else if(r == '\"' && !holdDoubleQuotes) holdDoubleQuotes = true;
}
return numberOfC;
}
输出:
3
另一种方法是使用正则表达式:
public static int countCharOfString(char c, String s)
{
s = " " + s + " "; // To make the first and last commas to be counted
return s.split("[^\"" + c + "*\"][" + c + "]").length - 1;
}
- 您不应该在循环中多次调用
。请使用charAt()
变量char
- 您不应该为每次迭代调用
。在循环之前使用length()
int
- 应避免与
重复比较-使用嵌套的if/elsec
- 您还可以使用正则表达式和String.split()
它可能看起来像这样:
public int countNonQuotedOccurrences(String inputstring, char searchChar)
{
String regexPattern = "[^\"]" + searchChar + "[^\"]";
return inputString.split(regexPattern).length - 1;
}
免责声明:
这只是显示了基本方法
上述代码不会在字符串的开头或结尾检查searchChar
您可以手动检查或添加到regexpatern。可能不是最快的
public int countCharOfString(char c, String s) {
final String removedQuoted = s.replaceAll("\".*?\"", "");
int total = 0;
for(int i = 0; i < removedQuoted.length(); ++i)
if(removedQuoted.charAt(i) == c)
++total;
return total;
}
public int countCharOfString(字符c,字符串s){
最后一个字符串removedQuoted=s.replaceAll(“\”*?\”,“”);
int-total=0;
对于(int i=0;i
此实现有两个区别:
- 使用
代替字符串CharSequence
- 如果我们在引用的子序列中,则无需使用
布尔值来跟踪
public static int countCharOfString(char quote, CharSequence sequence) {
int total = 0, length = sequence.length();
for(int i = 0; i < length; i++){
char c = sequence.charAt(i);
if (c == '"') {
// Skip quoted sequence
for (i++; i < length && sequence.charAt(i)!='"'; i++) {}
} else if (c == quote) {
total++;
}
}
return total;
}
公共静态int countCharOfString(char引号,CharSequence序列){
int total=0,length=sequence.length();
for(int i=0;i
需要一个大字符串才能产生巨大的差异
此代码速度更快的原因是,它平均每个循环包含1.5个检查,而不是每个循环包含3个检查。它使用两个循环来实现这一点,一个用于引用,另一个用于未引用状态
public static void main(String... args) {
String s = generateString(20 * 1024 * 1024);
for (int i = 0; i < 15; i++) {
long start = System.nanoTime();
countCharOfString(',', s);
long mid = System.nanoTime();
countCharOfString2(',', s);
long end = System.nanoTime();
System.out.printf("countCharOfString() took %.3f ms, countCharOfString2() took %.3f ms%n",
(mid - start) / 1e6, (end - mid) / 1e6);
}
}
private static String generateString(int length) {
StringBuilder sb = new StringBuilder(length);
Random rand = new Random(1);
while (sb.length() < length)
sb.append((char) (rand.nextInt(96) + 32)); // includes , and "
return sb.toString();
}
public static int countCharOfString2(char c, String s) {
int numberOfC = 0, i = 0;
while (i < s.length()) {
// not quoted
while (i < s.length()) {
char ch = s.charAt(i++);
if (ch == c)
numberOfC++;
else if (ch == '"')
break;
}
// quoted
while (i < s.length()) {
char ch = s.charAt(i++);
if (ch == '"')
break;
}
}
return numberOfC;
}
public static int countCharOfString(char c, String s) {
int numberOfC = 0;
boolean doubleQuotesFound = false;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == c && !doubleQuotesFound) {
numberOfC++;
} else if (s.charAt(i) == c && doubleQuotesFound) {
continue;
} else if (s.charAt(i) == '\"') {
doubleQuotesFound = !doubleQuotesFound;
}
}
return numberOfC;
}
更简单,更不容易出现错误(是的,与逐字符遍历字符串并手动跟踪所有内容相比,性能更低):
用switch语句替换if/else内容。我手头没有Java编译器处理程序,但如果引号中有多个逗号,它看起来会失败。使用if(r==c&&!holdDoubleQuotes)会更好吗numberOfC++;然后删除numberOfC--稍后?我不喜欢拆分的是,如果字符串以
char c
结尾,它们将不会被计数。例如Hi,How,Are,You,,,,
将返回3,而不是6。感谢您的时间和帮助!我正要添加这一点……当字符位于开头或结尾时,上述代码将无法工作您可以单独测试或添加一些“或”“ed正则表达式。String.split
使用正则表达式。对于这样简单的字符串操作,正则表达式非常昂贵。事实上,我分析了它,它更耗时。我感谢你的帮助@BRabbit27:因为它涉及正则表达式,所以它可能是这里最慢的解决方案,但也是最短的解决方案之一:)
public static void main(String... args) {
String s = generateString(20 * 1024 * 1024);
for (int i = 0; i < 15; i++) {
long start = System.nanoTime();
countCharOfString(',', s);
long mid = System.nanoTime();
countCharOfString2(',', s);
long end = System.nanoTime();
System.out.printf("countCharOfString() took %.3f ms, countCharOfString2() took %.3f ms%n",
(mid - start) / 1e6, (end - mid) / 1e6);
}
}
private static String generateString(int length) {
StringBuilder sb = new StringBuilder(length);
Random rand = new Random(1);
while (sb.length() < length)
sb.append((char) (rand.nextInt(96) + 32)); // includes , and "
return sb.toString();
}
public static int countCharOfString2(char c, String s) {
int numberOfC = 0, i = 0;
while (i < s.length()) {
// not quoted
while (i < s.length()) {
char ch = s.charAt(i++);
if (ch == c)
numberOfC++;
else if (ch == '"')
break;
}
// quoted
while (i < s.length()) {
char ch = s.charAt(i++);
if (ch == '"')
break;
}
}
return numberOfC;
}
public static int countCharOfString(char c, String s) {
int numberOfC = 0;
boolean doubleQuotesFound = false;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == c && !doubleQuotesFound) {
numberOfC++;
} else if (s.charAt(i) == c && doubleQuotesFound) {
continue;
} else if (s.charAt(i) == '\"') {
doubleQuotesFound = !doubleQuotesFound;
}
}
return numberOfC;
}
countCharOfString() took 33.348 ms, countCharOfString2() took 31.381 ms
countCharOfString() took 28.265 ms, countCharOfString2() took 25.801 ms
countCharOfString() took 28.142 ms, countCharOfString2() took 14.576 ms
countCharOfString() took 28.372 ms, countCharOfString2() took 14.540 ms
countCharOfString() took 28.191 ms, countCharOfString2() took 14.616 ms
public static int countCharOfString(char c, String s) {
s = s.replaceAll("\".*?\"", "");
int cnt = 0;
for (int foundAt = s.indexOf(c); foundAt > -1; foundAt = s.indexOf(c, foundAt+1))
cnt++;
return cnt;
}