如何删除重复项?

时间:2013-05-16 23:36:13

标签: java arrays

我无法从已填充随机整数的数组中删除重复项。我编写了一个java类来生成随机数,在我的主程序中,我调用了这些随机数,将这些数字写入.txt文件。然后我将从这个.txt文件读入并将它们存储在一个新的数组中,删除任何重复项。接下来,我必须将新的随机数写入一个新的.txt文件,其中第一行和最后一行的编号最小。因此,新列表中的顺序无关紧要。

我的问题是我不确定如何删除重复项。我可以从其他问题中看到人们说要使用Set或hashset,但我已经研究过这些。那么还有另一种通过循环遍历数组或其他东西来删除它们的方法吗?

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 个答案:

答案 0 :(得分:2)

时间, O(nlogn)是最好的选择,通过:array转换为Set然后将其转换回来:

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);
}

答案 1 :(得分:1)

如果必须使用数组,那么最简单的方法是在添加数字之前检查数字是否重复(通过循环遍历数组,检查新生成的随机数是否等于任何数字)数组中的值,如果是,则仅将其添加到数组的末尾。)

然而,其他人在他们建议在这种情况下使用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.你应该阅读并研究HashSets,因为它们是一个基本的,经常使用的数据结构(可能是列表中使用次数最多的第二种结构)。

答案 2 :(得分:1)

删除欺骗的最快方法是使用LinkedHashSet。由于此类Set旨在通过散列直接跳转到该值,因此不会向同一哈希索引添加两个值引用。

基本上,当您尝试添加相同项目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);

答案 3 :(得分:0)

排序和删除重复项,不使用除数组之外的任何内容,假设数组不为空(如果为空,则正确的答案是返回另一个空数组):

// 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,那么代码就更清晰:无需先通过查找大小和第二遍来填写内容。除非有很多重复,此代码比使用任何类型的集合要快得多,因为没有涉及查找。