【问题标题】:What's wrong with my algorithm that's giving me incorrect duplicate removal values?我的算法给我不正确的重复删除值有什么问题?
【发布时间】:2019-07-30 15:21:40
【问题描述】:

我正在尝试删除字符串中的重复项,但我不确定我的算法为何出错。它给了我baa 的输出,而不是正确的输出bans

在尝试调试期间,我尝试将sb.deleteCharAt(); 内部的i 切换为j,但这给了我一个Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 5 错误。

我做错了什么,我该如何解决?

这是我的代码:

public static void removeDuplicate(String s) {
    StringBuilder sb = new StringBuilder(s);

    for(int i = 0; i < s.length(); i++) {
        for(int j = i + 1; j < s.length(); j++) {
            if(s.charAt(i) == s.charAt(j)) {
                sb.deleteCharAt(i);
            }
        }
    }
    System.out.print("Duplicates have been, the resulting string is => " + sb);
}

public static void main(String[] args) {
    String s = "bananas";
    removeDuplicate(s);
}

【问题讨论】:

标签: java string algorithm for-loop char


【解决方案1】:

有几件事是错误的。您应该在循环中与字符串生成器进行比较,而不是与字符串本身进行比较,因为它会发生变化。其次,您在删除时使用了错误的索引。这是正确的程序:

public static void removeDuplicate(String s) {
    StringBuilder sb = new StringBuilder(s);

    for(int i = 0; i < sb.length(); i++) {
        for(int j = i + 1; j < sb.length(); j++) {
            if(sb.charAt(i) == sb.charAt(j)) {
                sb.deleteCharAt(j);
            }
        }
    }
    System.out.print("Duplicates have been, the resulting string is => " + sb);
}

public static void main(String[] args) {
    String s = "bananas";
    removeDuplicate(s);
}

输出是:

重复了,得到的字符串是=>bans

【讨论】:

    【解决方案2】:

    你可以使用distinct()

    StringBuilder sb = new StringBuilder();
    yourstr.chars().distinct().forEach(c -> sb.append((char) c));
    

    最好的

    【讨论】:

      【解决方案3】:

      好吧,从集合中删除元素 while 循环遍历它是一个坏主意,因为它可能会导致基于索引更改的错误逻辑。 只需放置一些特殊情况,例如“baaana”,您的解决方案将很容易失败,因为当您尝试在索引 2 处找到“a”时,您将其删除并跳过与“实际”索引 3 的比较,因为它的索引在删除后降至 2 . 还有一件事你应该知道。在 Java 中,String 是不可变的,这意味着当您更改一个字符串时,您实际上是用新的变量分配了该变量。所以这些函数应该返回一个新的字符串而不是修改输入。

      对于这种类型的问题,我建议你应该使用哈希数据类型来记忆不同的元素,这样你就可以用 O(n) 时间复杂度来解决这个问题。

      public static String removeDuplicate(String s) {
          StringBuilder sb = new StringBuilder();
          Set<Character> metChars = new HashSet<>();
          for(int i = 0; i < s.length(); i++) {
              char c = s.charAt(i);
              if(!metChars.contains(c)) {
                  sb.append(c);
                  metChars.add(c);
              }
          }
          return sb.toString();
      }
      

      【讨论】:

        【解决方案4】:

        基本上,当您删除 StringBuilder 中的一个字符时,您实际上会更改所有其他字符的索引。

        在您的示例 bananas 中,如果您删除第二个 a(位置 3,因为我们从 0 开始),您将得到字符串 bannas。然后,当你想删除 bananas 的第三个 a 时,在 pos 5,你最终删除了 s。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-11-23
          • 1970-01-01
          • 2012-12-03
          • 1970-01-01
          • 2014-01-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多