繁体   English   中英

有没有更有效的方法来计算每个连续字母在字符串中出现的次数? (爪哇)

[英]Is there a more efficient way to count the number of times each consecutive letter appears in a string? (java)

我正在制作一种方法,该方法采用指定的字符串并计算每个连续字母出现的次数。
例如:encode("aabbcc"); 应该给出 output 2 2 2,因为有 2 个字母依次出现

我的代码是:

for(int i=0;i<word.length()-1;i++) {
    int count=1;

    if(i!=word.length()-1) {
        //System.out.println(word.charAt(i));
        //System.out.println(word.charAt(i+1));
        try {
            while(word.charAt(i)==word.charAt(i+1)) {
                count++;
                i++;
            }
        } catch (Exception e) {}

        System.out.print(count+" ");
    }
}

但它一直给我一个IndexOutOfBoundsException所以我只是添加了一个 try and catch 块但我知道有更好的方法

不要像这个word.charAt(i)==word.charAt(i+1)那样向前看,因为这会给你错误。 相反,检查索引i处的字母是否与上一次迭代中的字母相同 - 如果是,则增加计数器。

另一种方法是使用正则表达式。

String str = "aabbccxa";
String result = Pattern.compile("(?<=(.))(?!\\1)")
                       .splitAsStream(str)
                       .map(e -> String.valueOf(e.length()))
                       .collect(Collectors.joining(" "));
System.out.println(result);

这个怎么运作:

  • 将字符串拆分为相同字符的组
  • map 每组至其长度
  • 使用空间作为分隔符进行收集

如果这比其他答案更好,我认为这是一个品味问题。 比简单的循环更有效? 我认为这也取决于输入。

欢迎来到 SO。 通常,如果您收到异常,您需要找出原因而不是添加捕获。

一个更简单的解决方案是:

Deque<Integer> counts = new LinkedList<>();
for (int i = 0; i < word.length(); i++) {
    if (i > 0 && word.charAt(i) == word.charAt(i - 1))
        counts.addLast(count.removeLast() + 1);
    else
        counts.addLast(1);
}

在循环结束时, i+1超出范围。

你可以这样计算它们:

if(i > 0 && word.charAt(i) == word.charAt(i - 1))

您可以在while循环条件中测试i + 1是否小于word.length() 您也可以将word.length()保存到局部变量中。 喜欢,

int len = word.length();
for (int i = 0; i < len - 1; i++) {
    int count = 1;
    while (i + 1 < len && word.charAt(i) == word.charAt(i + 1)) {
        count++;
        i++;
    }
    System.out.print(count + " ");
}
    String str="aabbbccaaaacds";
    boolean flag=false;
    int cnt=1;
    for (int i = 0; i < (str.length()-1); i++) {  // iterate till length -1 as we are using str.charAt(i+1) 
        if(str.charAt(i)==str.charAt(i+1)) {
            flag=true; // keep flag as true till matching chars
            cnt=cnt+1;
        }
        else {
            flag=false; 
        }
        if(flag==false && cnt>=2) {
            System.out.println("char="+str.charAt(i)+", occurance="+cnt);
            cnt=1;
        }
        if(i==(str.length()-2) && flag) { // only used when we are at comparing last two characters
            System.out.println("char="+str.charAt(i)+", occurance="+cnt);
        }

    }

Output:

char=a, occurance=2
char=b, occurance=3
char=c, occurance=2
char=a, occurance=4

您可以将它们收集在 map 中并打印出来。 这会打印出与计数匹配的实际字符串,但可以根据需要轻松定制。

      String str = "aabbbbcccccdddddaaaaz";

      Map<Integer, List<String>> freq = Arrays.stream(
            str.replaceAll("(([a-z])\\2*)", "$1,").split(",")).filter(
                  a -> a.length() > 1).collect(
                        Collectors.groupingBy(String::length));

      freq.forEach((k, v) -> System.out.println(k + " : " + v));

打印以下内容。

2:[aa]
4:[bbbb,aaaa]
5:[cccc,dddd]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM