4

重複がある場所のインデックスを格納する一時配列を作成してリストから重複を削除しようとしています。次に、インデックスを最初の一時配列に格納したインデックスと比較しながら、元の配列を別の一時配列にコピーします。 。

public void removeDuplicates()
{
    double tempa [] = new double [items.length];
    int counter = 0;
    for ( int i = 0; i< numItems ; i++)
    {
        for(int j = i + 1; j < numItems; j++)
        {
            if(items[i] ==items[j])
            {
                tempa[counter] = j;
                counter++;

            }
        }
    }

    double tempb [] = new double [ items.length];
    int counter2 = 0;
    int j =0;
    for(int i = 0; i < numItems; i++)
    {
        if(i != tempa[j])
        {
            tempb[counter2] = items[i];
            counter2++;

        }
        else
        {
            j++;

        }
    }

    items = tempb;
    numItems = counter2;
}

ロジックは正しいように見えますが、私のコンパイラは、でarrayindexoutofboundsエラーを出します。

tempa[counter] = j;

カウンターがitems.lengthの値を超えるまでどのように成長するのかわかりませんが、ロジックの欠陥はどこにありますか?

4

8 に答える 8

13

あなたは自分自身のために物事を非常に困難にしています。面倒な作業は Java に任せましょう。たとえば、LinkedHashSet は一意性を提供し、挿入順序を保持します。また、すべての値を他のすべての値と比較するよりも効率的です。

double [] input = {1,2,3,3,4,4};
Set<Double> tmp = new LinkedHashSet<Double>();
for (Double each : input) {
    tmp.add(each);
}
double [] output = new double[tmp.size()];
int i = 0;
for (Double each : tmp) {
    output[i++] = each;
}
System.out.println(Arrays.toString(output));
于 2012-09-28T01:05:20.380 に答える
2
import java.util.HashSet;

import sun.security.util.Length;


public class arrayduplication {
public static void main(String[] args) {
        int arr[]={1,5,1,2,5,2,10};
        TreeSet< Integer>set=new TreeSet<Integer>();
        for(int i=0;i<arr.length;i++){
            set.add(Integer.valueOf(arr[i]));
        }
        System.out.println(set);


    }

}
于 2013-09-28T20:55:22.437 に答える
2

これが入力データであると想像してください。

Index: 0, 1, 2, 3, 4, 5, 6, 7, 8
Value: 1, 2, 3, 3, 3, 3, 3, 3, 3

次に、アルゴリズムによると、次のようにtempaする必要があります。

Index: 0, 1, 2, 3, 4, 5, 6, 7, 8, ....Exception!!!
Value: 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 5, 6, 7, 8, 6, 7, 8, 7, 8, 8

なぜこの問題があるのですか?ネストされた for ループの最初のセットは、重複する配列インデックスの重複を挿入しようとすることを妨げるものではないためです!

最善の解決策は何ですか?

セットを使おう! セットは、重複するエントリがないことを保証します。新しい Set を作成し、すべての配列項目をそれに追加すると、Set は重複を削除します。次に、Set から配列に戻るだけです。

別の方法として、同じことを行う非常にC的な方法を次に示します。

//duplicates will be a truth table indicating which indices are duplicates.
//initially all values are set to false
boolean duplicates[] = new boolean[items.length];
for ( int i = 0; i< numItems ; i++) {
    if (!duplicates[i]) { //if i is not a known duplicate
        for(int j = i + 1; j < numItems; j++) {
            if(items[i] ==items[j]) {
                duplicates[j] = true; //mark j as a known duplicate
            }
        }
    }
}

どのように終了するかはあなたに任せます。

于 2012-09-28T01:03:13.047 に答える
0

セットを使用せず、プリミティブ型のみを使用する別の方法を次に示します。

public static double [] removeDuplicates(double arr[]) {
    double [] tempa = new double[arr.length];
    int uniqueCount = 0;
    for (int i=0;i<arr.length;i++) {
        boolean unique = true;
        for (int j=0;j<uniqueCount && unique;j++) {
            if (arr[i] == tempa[j]) {
                unique = false;
            }
        }
        if (unique) {
            tempa[uniqueCount++] = arr[i];
        }
    }

    return Arrays.copyOf(tempa,  uniqueCount);
}

実際の結果を得る途中で、doubleオブジェクトの一時的な配列が必要です。

于 2012-09-28T03:42:02.233 に答える
0

配列で行う代わりに、単純にjava.util.Set.

ここに例があります:

public static void main(String[] args)
{
    Double[] values = new Double[]{ 1.0, 2.0, 2.0, 2.0, 3.0, 10.0, 10.0 };
    Set<Double> singleValues = new HashSet<Double>();

    for (Double value : values)
    {
        singleValues.add(value);
    }
    System.out.println("singleValues: "+singleValues);
    // now convert it into double array
    Double[] dValues = singleValues.toArray(new Double[]{});
}
于 2012-09-28T01:05:43.870 に答える
0

すでにnum_itemsループをバインドするために使用しています。その変数を使用して、テンパの配列サイズも設定します。

double tempa [] = new double [num_items];
于 2012-09-28T01:02:27.023 に答える
0

セットを使用して倍数を削除できます。

于 2012-09-28T04:28:35.647 に答える