2

我正在尝试创建一种方法,该方法要么从字符串中删除所有重复项,要么根据参数仅在一行中保留相同的 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

4 回答 4

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' 中,只有第一个 l 匹配(部分 (?=\1)不是比赛的一部分)。所以第一个 l 被一个空字符串替换,我们留下了 helo,它与正则表达式不匹配

第二个模式是一样的,但这次我们期待第一组的两次出现,例如hello。另一方面,'hello' 将不匹配。

在这里寻找更多信息:正则表达式

PS如果有帮助,请免费填写以接受答案。

于 2013-04-17T07:52:05.097 回答
3

尝试

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

输出

helo
于 2013-04-17T07:53:16.660 回答
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();
}

我正在使用位来识别唯一性。

编辑:

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

于 2013-04-17T07:56:53.347 回答
1

以前面的 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);

它产生:

直升机

海洛

它能做什么:

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

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

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

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

于 2013-04-17T08:00:48.487 回答