删除数组重复项

时间:2013-07-14 18:47:04

标签: java algorithm

我正在尝试从数组中删除重复项,但它无效。

我错过了什么吗?

代码: -

class RemoveStringDuplicates {

    public static char[] removeDups(char[] str) {
        boolean bin_hash[] = new boolean[256];
        int ip_ind = 0, res_ind = 0;
        char temp;

        while (ip_ind < str.length) {
            temp = str[ip_ind];
            if (bin_hash[temp] == false) {
                bin_hash[temp] = true;
                str[res_ind] = str[ip_ind];
                res_ind++;
            }
            ip_ind++;
        }

        return str;
    }

    public static void main(String[] args) {
        char str[] = "test string".toCharArray();
        System.out.println(removeDups(str));
    }
}

输出: -

 tes ringing //ing should not have been repeated!

6 个答案:

答案 0 :(得分:2)

您应该使用新数组,而不是将字符分配到同一个数组中。因为,在删除重复项后,不会删除尾随元素,因此会打印出来。

因此,如果使用新数组,则尾随元素将为null个字符。

所以,只需创建一个新数组:

char[] unique = new char[str.length];

然后更改作业:

str[res_ind] = str[ip_ind];

为:

unique[res_ind] = str[ip_ind];

此外,您可以考虑使用ArrayList代替array。这样你就不必为每个角色维护一个boolean数组,这太过分了。你正在失去一些不需要的额外空间。使用ArrayList,您可以使用contains方法检查已添加的字符。

嗯,您还可以使用Set手动避免手动执行所有这些计数工作,这会自动为您删除重复项。但大多数实现都不维护插入顺序。为此,您可以使用LinkedHashSet

答案 1 :(得分:1)

具体问题已经找到了解决方案,但是如果您没有限制使用自己的方法并且可以使用java库,我会建议这样的事情:

public class RemoveDuplicates {

// Note must wrap primitives for generics
// Generic array creation not supported by java, gotta return a list

public static <T> List<T> removeDuplicatesFromArray(T[] array) {
    Set<T> set = new LinkedHashSet<>(Arrays.asList(array));
    return new ArrayList<>(set);
}

public static void main(String[] args) {
    String s = "Helloo I am a string with duplicates";
    Character[] c = new Character[s.length()];

    for (int i = 0; i < s.length(); i++) {
        c[i] = s.charAt(i);
    }

    List<Character> noDuplicates = removeDuplicatesFromArray(c);
    Character[] noDuplicatesArray = new Character[noDuplicates.size()];
    noDuplicates.toArray(noDuplicatesArray);

    System.out.println("List:");
    System.out.println(noDuplicates);
    System.out.println("\nArray:");
    System.out.println(Arrays.toString(noDuplicatesArray));
}
}

出:

List:
[H, e, l, o,  , I, a, m, s, t, r, i, n, g, w, h, d, u, p, c]

Array:
[H, e, l, o,  , I, a, m, s, t, r, i, n, g, w, h, d, u, p, c]

linkedhashset保留了排序,这对于像字符集这样的事情可能尤为重要。

答案 2 :(得分:0)

试试这个:

public static char[] removeDups(char[] str) {
        boolean bin_hash[] = new boolean[256];
        int ip_ind = 0, res_ind = 0;
        char temp;
        char a[] = new char[str.length];

        while (ip_ind < str.length) {
            temp = str[ip_ind];
            if (bin_hash[temp] == false) {
                bin_hash[temp] = true;
                a[res_ind] = str[ip_ind];
                res_ind++;
            }
            ip_ind++;
        }

        return a;
    }

你基本上是在循环中更新str变量。更新它并再次循环更新的数组。

答案 3 :(得分:0)

我认为问题是由于您在修改str时进行迭代(由行str[res_ind] = str[ip_ind])引起的。如果将结果复制到另一个数组,它可以工作:

class RemoveStringDuplicates {

    public static char[] removeDups(char[] str) {
        char result[] = new char[str.length];
        boolean bin_hash[] = new boolean[256];
        int ip_ind = 0, res_ind = 0;
        char temp;

        while (ip_ind < str.length) {
            temp = str[ip_ind];
            if (bin_hash[temp] == false) {
                bin_hash[temp] = true;
                result[res_ind] = str[ip_ind];
                res_ind++;
            }
            ip_ind++;
        }

        return result;
    }

    public static void main(String[] args) {
        char str[] = "test string".toCharArray();
        System.out.println(removeDups(str));
    }
}

答案 4 :(得分:0)

所有其他答案似乎都是正确的。您在结果末尾看到的“ing”实际上是数组中已经存在的未触摸字符。

作为替代解决方案(如果你想节省内存),你可以循环遍历数组的最后一部分以删除最后的字符,因为你已经知道它们是重复的。

//C# code, I think you just need to change str.Length here to str.length
for (int delChars = res_ind; delChars < str.Length; delChars++)
{
    str[delChars] = '\0';
}

答案 5 :(得分:0)

您完全滥用Java语言和代码。标准库中的数据结构类是使用Java 的要点。使用它们。

正确的编码方式来做你想做的事情就在这里:

class RemoveStringDuplicates {

    public static String removeDups(CharSequence str) {

        StringBuilder b = new StringBuilder(str);
        HashSet<Character> s = new HashSet<Character>();

        for(int idx = 0; idx < b.size(); idx++)
            if(mySet.contains(b.charAt(idx)))
                b.deleteCharAt(idx--);
            else
                s.add(ch);

        return b.toString();
    }

    public static void main(String[] args) {
        System.out.println(removeDups(str));
    }
}

也可能有更好的方法。不要避免使用Java的数据结构。

如果您编写的代码对性能非常敏感,您必须使用问题中的原始代码,那么您应该使用其他语言,例如C.