给我不正确的重复删除值的算法有什么问题?

时间:2019-03-08 14:59:18

标签: java algorithm debugging

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

在尝试调试期间,我尝试在i内部将j切换为sb.deleteCharAt();,但这给了我一个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);
}

4 个答案:

答案 0 :(得分: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);
}

输出为:

  

已重复,结果字符串为=>禁止

答案 1 :(得分:1)

您可以使用distinct()

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

最佳

答案 2 :(得分:0)

基本上,当您删除StringBuilder中的字符时,可以有效地更改所有其他字符的索引。

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

答案 3 :(得分:0)

嗯,在循环中删除集合中的元素是一个坏主意,因为它可能基于索引更改导致错误的逻辑。 只需添加诸如“ baaana”之类的特殊情况,您的解决方案就很容易失败,因为当您尝试在索引2处找到“ a”时,您将其删除并跳过与“实际”索引3的比较,因为删除后其索引会减少为2 。 还有另一件事你应该知道。在Java中,String是不可变的,这意味着当您更改字符串时,实际上是为变量分配了新变量。因此,这些函数应该返回一个新的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();
}