删除一行中重复的相同字符

时间:2013-04-17 07:42:57

标签: java

我正在尝试创建一个方法,该方法将从字符串中删除所有重复项,或者仅根据参数在一行中保留相同的2个字符。

例如:

helllllllo -> helo

helllllllo -> hello - 这会保留双字母

目前我通过执行以下操作删除重复项:

private String removeDuplicates(String word) {
    StringBuffer buffer = new StringBuffer();
    for (int i = 0; i < word.length(); i++) {
        char letter = word.charAt(i);
        if (buffer.length() == 0 && letter != buffer.charAt(buffer.length() - 1)) {
            buffer.append(letter);
        }
    }
    return buffer.toString();
}

如果我想保留双字母,我正在考虑使用类似私有字符串removeDuplicates(String word, boolean doubleLetter)

的方法

doubleLetter为真时,它将返回hello而不是helo

我不确定在不重复大量代码的情况下最有效的方法。

4 个答案:

答案 0 :(得分:5)

为什么不使用正则表达式?

 public class RemoveDuplicates {
      public static void main(String[] args) {
           System.out.println(new RemoveDuplicates().result("hellllo", false)); //helo
           System.out.println(new RemoveDuplicates().result("hellllo", true)); //hello
      }

      public String result(String input, boolean doubleLetter){
           String pattern = null;
           if(doubleLetter) pattern = "(.)(?=\\1{2})";
           else pattern = "(.)(?=\\1)";
       return input.replaceAll(pattern, "");
      }
 }

 (.)    --> matches any character and puts in group 1. 
 ?=     --> this is called a positive lookahead. 
 ?=\\1  --> positive lookahead for the first group

总的来说,这个正则表达式本身会查找所遵循的任何字符(正向前瞻)。例如aa或bb等。重要的是要注意,实际上只有第一个字符是匹配的一部分,因此在单词'hello'中,只匹配第一个字符(部分(?= \ 1)是< strong>不是比赛的一部分)。所以第一个l被一个空字符串替换,我们留下了helo,这与正则表达式不匹配

第二种模式是相同的,但这次我们展望第一组的两次出现,例如helllo。另一方面'你好'将不会匹配。

在这里查看更多内容:Regex

P.S。如果有帮助,请填写免费接受答案。

答案 1 :(得分:3)

    String s = "helllllllo";
    System.out.println(s.replaceAll("(\\w)\\1+", "$1"));

输出

helo

答案 2 :(得分:1)

试试这个,这将是最有效的方式[评论后编辑]:

public static String removeDuplicates(String str) {
    int checker = 0;
    StringBuffer buffer = new StringBuffer();
    for (int i = 0; i < str.length(); ++i) {
        int val = str.charAt(i) - 'a';
        if ((checker & (1 << val)) == 0)
            buffer.append(str.charAt(i));
        checker |= (1 << val);
    }
    return buffer.toString();
}

我使用位来识别唯一性。

编辑:

整个逻辑是,如果一个字符已被解析,那么它的相应位被设置,并且下一次当该字符出现时,它将不会被添加到字符串缓冲区中,相应的位已被设置。

答案 3 :(得分:1)

this之前的SO示例为出发点,我提出了这个问题:

    String str1= "Heelllllllllllooooooooooo";

    String removedRepeated = str1.replaceAll("(\\w)\\1+", "$1");
    System.out.println(removedRepeated);

    String keepDouble = str1.replaceAll("(\\w)\\1{2,}", "$1");
    System.out.println(keepDouble);

它产生:

  

西洛

     

Heelo

它的作用:

(\\w)\\1+将匹配任何字母并将其放入正则表达式捕获组中。稍后可以通过\\1+访问该组。这意味着它将匹配前一个字母的一个或多个重复。

(\\w)\\1{2,}与上面相同,唯一的区别是它只关注重复次数超过2次的字符。这使双字符保持不变。

编辑: 重新阅读问题,似乎你想用双打替换多个字符。为此,只需使用以下行:

String keepDouble = str1.replaceAll("(\\w)\\1+", "$1$1");