-1

配列から重複を削除しようとしていますが、機能していません。

何か不足していますか?

コード:-

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!
4

6 に答える 6

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

于 2013-07-14T18:53:04.123 に答える
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]

リンクされたハッシュセットは順序を保持します。これは、文字配列などで特に重要になる可能性があります。

于 2013-07-14T19:23:40.670 に答える
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 変数を更新しています。それを更新し、更新された配列で再度ループします。

于 2013-07-14T18:52:59.273 に答える
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));
    }
}
于 2013-07-14T18:53:34.323 に答える
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';
}
于 2013-07-14T18:58:14.610 に答える
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 などの別の言語を使用する必要があります。

于 2013-07-14T18:59:49.023 に答える