我无法从已填充随机整数的数组中删除重复项。我编写了一个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]);
}
}
}
}
}
}
答案 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
,那么代码就更清晰:无需先通过查找大小和第二遍来填写内容。除非有很多重复,此代码比使用任何类型的集合要快得多,因为没有涉及查找。