【问题标题】:How to remove adjacent duplicates in a string in Java如何在Java中删除字符串中的相邻重复项
【发布时间】:2017-04-16 11:45:12
【问题描述】:

我一直在寻找这个答案。 我找到了许多使用 HashSet 或 LinkedHashSet 删除重复项的解决方案,但它们都删除了所有重复项,我只寻找相邻的。 " 说一个字符串是“ABBCDAABBBBBBBBOR” 所需的结果应该是“ABCDABOR”而不是“ABCDOR”。 这可以在 O(n) 中实现吗?谢谢。

【问题讨论】:

  • 我真的很想看看 Java-8 + 正则表达式的例子...

标签: java string duplicates


【解决方案1】:

当然:

StringBuilder sb = new StringBuilder();
char[] chars = text.toCharArray();
char previous = chars[0];
sb.append(chars[0]);
for(int i = 1 ; i < chars.length ; i++) {
    if(chars[i] != previous) {
        sb.append(chars[i]);
        previous = chars[i];
    }
}
String res = sb.toString();

【讨论】:

    【解决方案2】:

    我刚刚开始使用流,所以请耐心等待......

    public static String removeAdjacentDuplicates(String input) {
        if (input.length() <= 1) {
            return input;
        }
    
        StringBuilder sb = new StringBuilder();
        sb.append(input.charAt(0));
    
        IntStream.range(1, input.length())
            .mapToObj(i -> input.charAt(i) != input.charAt(i - 1) ? input.charAt(i) : "")
            .forEach(sb::append);
    
        return sb.toString();
    }
    

    或者如果这更像你的风格而不是 StringBuilder:

    return input.charAt(0) + String.join("", 
        IntStream.range(1, input.length())
            .mapToObj(i -> input.charAt(i) != input.charAt(i - 1) ?
                String.valueOf(input.charAt(i)) : "")
            .toArray(size -> new String[size]));
    

    【讨论】:

      【解决方案3】:

      O(n) 时间解:

      public String removeAdjacentDuplicates(String s) {
          StringBuilder resultBuilder = new StringBuilder();
          char previous = s.charAt(0);
          resultBuilder.append(previous);
          for (int i = 1; i < s.length(); i++) {
              char current = s.charAt(i);
              if (previous != current) {
                  resultBuilder.append(current);
                  previous = current;
              }
          }
          return resultBuilder.toString();
      }
      

      【讨论】:

      • O(n) 时间,是的,但也有 O(n) 空间。 StringBuilder resultBuilder 的大小与 String 的大小直接相关。我看到使其成为 O(1) 空间的唯一实用方法是,如果从未存储过重复数据删除的字符串;您必须在处理时输出它。只要该方法必须返回一个单独的去重字符串,那么您将需要与输入字符串的大小直接相关的额外存储空间。但是,如果输入是一个 char 数组,那么您可以重用传递的数组,但所有您需要花费 O(n^2) 时间的交换。空间与时间,一如既往。
      • 好点,但用于存储结果的空间在空间复杂度分析中几乎总是被忽略。
      • 这种方法正是我会写的那种东西。当我看到这个问题时,我认为 OP 意味着时间,直到我在这里看到它时才想到空间。我假设这个问题来自一个学生,并认为我们应该提供最准确的答案。该算法使用的空间随着输入字符串中的字符数线性增加,因此 O(n)。 O(1) 意味着算法使用的空间是恒定的;无论输入字符串的长度如何,它都会消耗相同数量的空间。
      • 我完全同意。编辑原始答案。
      【解决方案4】:

      这是一个使用 Java 的完整解决方案。

      public class Occurence2 {
      
          public static void main(String[] args) {
              // String a = "ABBCDAABBBBBBBBOR"; //ABCDABOR
              String a = "GiiinnnniiiiiGinnnaPrrooottijayyyi";//GiniGinaProtijayi
              fix(a);
          }// amin
      
          private static void fix(String a) {
              StringBuffer sbr = new StringBuffer();
              for (int i = 0; i < a.length(); i++) {
                  char ch = a.charAt(i);
                  if (sbr.length() == 0) {
                      sbr.append(ch);
                  }
                  if (ch == sbr.charAt(sbr.length() - 1)) {
                      i++;
                  } else {
                      sbr.append(ch);
                  }
              }
              System.out.println(sbr);
          }// fiix
      }
      

      如果你不想使用StringBuffer,那么你可以简单地使用一个空字符串。

      public class Test6 {
      public static void main(String[] args) {
          String a = "GiiinnnniiiiiGinnnaPrrooottijayyyi";
          fix(a);
          }
      
      private static void fix(String a) {
            String res = "";
          int i = 0 ;
           while(i < a.length()) {
               char ch = a.charAt(i);
               if(res.length() == 0 ) {res += ch ;}
               if(ch == res.charAt(res.length() -1)) {i++ ;}
               if(ch != res.charAt(res.length() -1)) {res += ch ;}
           }//while
            System.out.println(res);
      }//fix
      
      }
      

      Python 中的解决方案:

      a = "GiniiiiGinaaaPrrrottiijayi"
      
      reslist =[]
      for ch in a:
           if(len(reslist) == 0 or ch != reslist[-1]):reslist.append(ch)
      
      print(reslist)
      print(''.join(reslist))   
      

      【讨论】:

        猜你喜欢
        • 2018-03-05
        • 1970-01-01
        • 1970-01-01
        • 2021-08-04
        • 2021-09-29
        • 1970-01-01
        • 2011-06-26
        • 1970-01-01
        相关资源
        最近更新 更多