1

ランダムな整数を取り込んだ配列から重複を削除するのに問題があります。乱数を生成する Java クラスを作成し、メイン プログラムでこれらの乱数を呼び出して、これらを .txt ファイルに書き込みました。次に、この .txt ファイルから読み取り、重複を削除して新しい配列に保存します。次に、乱数の新しいセットを新しい .txt ファイルに書き直さなければなりません。最初の行に最小の数値、最後に最大の数値を指定します。したがって、新しいリストでの順序は重要ではありません。

私の問題は、重複を削除する方法がわからないことです。投稿された他の質問から、人々がセットまたはハッシュセットを使用するように言っていることがわかりますが、私はこれらをまだ調査しています。では、配列などをループしてそれらを削除する別の方法はありますか?

import java.io.*;
class MainProg{

    public static void main (String[]args){

        GenKeys keys = new GenKeys();

        //System.out.println(keys.getrandom());
        //System.out.println(keys.getrandom());

        try{
                    String f = "keys.txt";
                    FileWriter fw = new FileWriter(f);
                    BufferedWriter bw = new BufferedWriter(fw);

                    for (int i=1; i<=500; i++){
                        //bw.write(i+ System.getProperty("line.separtor"));
                        bw.write(keys.getrandom() + "\r\n");
                    }

                    // close the file after all the writing has taken place
                    bw.close ();
                } catch (IOException e){
                    System.out.println ("Error writing to file" + e.toString());
        }


            // declare a place to store each line as it is read in
            String str;
            String myArray[] = new String [500];
            int i = 0;

                try{
                    FileReader fr = new FileReader("keys.txt");
                    BufferedReader in = new BufferedReader(fr);

                    // read in the first line from the file
                    str = in.readLine();
                    while(str!=null){

                    myArray[i] = str;

                    str = in.readLine();
                    i++;
                    }

                    // close the file
                    in.close();
                    }catch(IOException e){
                    System.out.print(e.toString());
                    System.out.print("Non-Existant File");
        }
            int [] mySortedArray = new int [500];
            for(int k = 0; k<mySortedArray.length;k++){
                for(int j = 0;j<mySortedArray.length;j++){
                    if(mySortedArray[j] != k){
                        mySortedArray[k] = j;
                        System.out.print(mySortedArray[k]);
                    }

            }
        }
    }

}
}
4

4 に答える 4

3

時間的には、O (nlogn)最善の策ですarraySet

Integer[] withDups = {1, 5, 2, 6, 3, 4, 2, 6, 3, 7};
Set<Integer> set = new TreeSet<Integer>(Arrays.asList(withDups));
Integer[] withoutDups = set.toArray(new Integer[set.size()]);
System.out.println(Arrays.toString(withoutDups));

出力:

[1, 2, 3, 4, 5, 6, 7]


セット (数学のセット) は、アイテムの重複を許可しないデータ構造です。

との間の変換に問題がある場合はint[]Integer[]ループを使用します。

int[] intArray = ...;

Integer[] integerArray = new Integer[intArray.length];
int i = 0;
for (int value : oldArray) {
    integerArray[i++] = Integer.valueOf(value);
}
于 2013-05-16T23:45:41.260 に答える
2

配列を使用する必要がある場合、最も簡単な方法は、追加する前に数値が重複していないことを確認することです (配列をループして、新しく生成された乱数が配列内の値と等しいかどうかを確認します)。配列であり、配列の末尾にある場合にのみ追加します。)

ただし、このシナリオで HashSet を使用することを提案している他の人は正しいです。これにより、設計により重複が防止されます (このチェックは無料で取得できます)。複雑ではありません。基本的な使用法は次のようになります。

HashSet<Integer> set = new HashSet<>();
set.put(1);
set.put(3);
set.put(5);
set.put(3);
for(int num : set) {
    System.out.println(num);
}

...これは 1、3、および 5 を出力します。HashSet は基本的で非常に頻繁に使用されるデータ構造であるため (おそらく、リストに次いで 2 番目によく使用される構造です)、HashSet を読んで学習することをお勧めします。

于 2013-05-16T23:43:02.827 に答える
2

重複を削除する最速の方法は、LinkedHashSet. このタイプのSetはハッシュによって値に直接ジャンプするように設計されているため、同じハッシュ インデックスに 2 つの値参照を追加することはありません。

基本的に、同じアイテムを n 回追加しようとすると、最初の操作以降のすべての操作は暗黙のうちに失敗します。返されるのは、重複していない配列です。

public static int[] removeDuplicates(int[] arr) {
    Set<Integer> tmp = new LinkedHashSet<Integer>();
    for (Integer item : arr) {
        tmp.add(item);
    }
    int[] output = new int[tmp.size()];
    int i = 0;
    for (Integer item : tmp) {
        output[i++] = item;
    }
    return output;

};
mySortedArray = removeDuplicates(mySortedArray);
于 2013-05-16T23:43:12.953 に答える
1

配列が空ではないと仮定して、配列以外は何も使用せずに重複をソートして削除します(空の場合、正しい答えは別の空の配列を返すことです)。

// sort the input
Arrays.sort(input);

// count unique elements in input
int unique=1;
for (int i=1; i<input.length; i++) {
   if (input[i] != input[i-1]) unique ++;
}

// create an output array of that size
int output[] = new int[unique];

// store unique copies of the (sorted) input elements
output[0] = input[0];
for (int i=1, j=1; i<input.length; i++) {
   if (input[i] != input[i-1]) output[j++] = input[i];
}

を自由に使用できた場合ArrayList、コードはよりクリーンになります。最初のパスでサイズを確認し、2 番目のパスで入力する必要はありません。多くの重複がない限り、このコードはセットを使用するよりもはるかに高速です。ルックアップが含まれていないためです。

于 2013-05-17T00:00:29.157 に答える