用不允许的出现次数替换字符串中所有连续的重复项

时间:2019-07-16 13:42:13

标签: java string algorithm

我需要编写一个方法,该方法将String作为参数,并返回通过将每个重复的相邻字母的实例替换为该字符串的'n'实例而获得的新String。

例如,如果将"aaabcccd"作为输入字符串,并将n =2作为输入字符串,它将返回"aabccd"。我已经尝试了以下代码,但未获得预期的输出

            String in = "aaadbbb";
            char[] s = in.toCharArray();
            int len = s.length;

            int n = 2;
            StringBuffer new_s = new StringBuffer("");
            int count = 1;
            char prev='\0';

            for (int i = 0; i < len - 1; i++) {
                if (s[i] == s[i + 1]) {
                   if(count <= n){
                        new_s.append(s[i]);
                       count++;
                    }else{
                     count=1;
                   }
                } else {
                    new_s.append(s[i]);
                }
            }

            System.out.println(new_s);

输出-aaadb 预期-aadbb

5 个答案:

答案 0 :(得分:3)

可以使用反向引用使用正则表达式魔术来完成。

String in = "aaaaddbbbbc";
int n = 2;
String pattern = String.format("(([a-z])\\2{%d})\\2+", n - 1);
System.out.println(in.replaceAll(pattern, "$1"));

输出:

  

aaddbbc

说明: {}中的数字是n-1

([a-z])是一个捕获组,匹配从a到z的任何单个小写字母。由于它是表达式中的第二组括号,因此可以引用为2

(([a-z])\\2{n})的意思是“匹配相同字母的n + 1个重复”。它组成了第一个捕获组,我们将其用作替换组

\\2+匹配同一字母的所有其他重复。更换后将其丢弃。

答案 1 :(得分:1)

我认为您在正确的轨道上。我不确定这是否是一项作业,所以我不想直接给你答案,但是这里有一些提示可能会有所帮助:

  1. 您已经在遍历字符串。这很棒!但是,我认为您想将 current 字符与上一个字符而不是下一个字符进行比较。
  2. 您无需将输入转换为char数组即可对其进行迭代,只需使用charAt(idx)
  3. 您似乎从未使用过prev,但我认为声明时会牢记正确的想法!
  4. 将问题分为两个部分:何时更新计数和何时添加字符。您可以在for循环中解决这两个问题,但是与其尝试在同一个if语句中同时做两件事,不如将它分解成多个ifs。

要做的三件事是:

  • 更新上一个值
  • 更新计数
  • 更新新的字符串

为这些事情找到正确的顺序以及我将交给您的确切实现(再次,因为我不确定这是否是一项任务)

更新:由于其他人已经发布,因此这是我的解决方案(带有单个for循环):

private String replaceConsecutiveDuplicates(String input, int n) {
    if (input == null || input.length() < n) return input;
    if (n == 0) return "";

    StringBuffer sb = new StringBuffer();

    int count = 1;
    char prev = input.charAt(0);
    sb.append(prev);

    char current;
    for( int i = 1; i < input.length(); i++) {
        current = input.charAt(i);
        if (prev == current) {
            if (++count > n) continue;
        } else {
            count = 1; 
        }
        prev = current;
        sb.append(current);
    }
    return sb.toString();
}

答案 2 :(得分:1)

    public static String test(String input, int repetitions) {
    String flag = "";
    String replacement = "";
    String output = input;
    ArrayList<Character> prevLetters = new ArrayList<Character>();

    for(int x = 0; x < input.length(); x++) {
        if(!prevLetters.contains(input.charAt(x))) {
            for(int y = 0; y <= repetitions ; y++) {
                flag += String.valueOf(input.charAt(x));
            }
            if(input.contains(flag)) {
                replacement = flag.substring(0, flag.length()-1);
                while(output.contains(flag)){
                    output = output.replace(flag, replacement);
                }
            }
            flag = "";
            prevLetters.add(input.charAt(x));
        }
    }
    return output;
}

这是我的解决方案,它遵循与您类似的想法。但是,我认为与其比较每个字符值,不如简单地检查规则是否有中断(字符连续出现n + 1次)并“修复”,会更容易。

如果您对使用您的方法感兴趣,我注意到的一个潜在问题是您没有将计数分配为1。您也没有机会添加最后一个字符,因为仅当循环的持续时间为len-1时才在索引“ i”处添加字符。

答案 3 :(得分:1)

要添加另一种替代方法:

    String in = "aaadbbbjjkllllllopp";
    int n = 2;
    StringBuilder sb = new StringBuilder();
    char temp = in.charAt(0);
    for(int i = 0; i < in.length()-1;){   // note that the incrementation of i is moved to the while loop
        temp = in.charAt(i);            // save current char in temp variable
        int count = 0;
        while (i < in.length() && in.charAt(i) == temp) {   ///iterate as long as you find same chars or hit the end of the string
            i++;
            count++;
        }
        if (count > n){   // if and only if count is greater than max allowed set it to max allowed
            count = n;
        }
        for(int j = 0; j < count; j++){   // append count chars
            sb.append(temp);
        }
    }
    System.out.println(sb.toString());

答案 4 :(得分:1)

看看这个解决方案。您应该注意输入字符串中的最后一个字符,因为您只迭代到最后一个字符,而不是一个。

private void replaceConsecutiveDuplicates() {
    String input = "aaadbbb";
    int n = 2;
    StringBuffer sb = new StringBuffer();
    int count = 1;
    char current;

    for( int i = 0; i < input.length(); ++i){
        current = input.charAt(i);
        if (i + 1 < input.length() && current == input.charAt(i + 1)) {
            ++count;
        } else if (count > 1) {
            for(int j = 0; j < n; ++j) {
                sb.append(current);
            }
            count = 1;
        }
        else {
            sb.append(current);
        }
    }
    System.out.println(sb.toString());
}