如何在Java中使用辅助数组从列表中删除重复项?

如何在Java中使用辅助数组从列表中删除重复项?,java,arrays,duplicates,counter,Java,Arrays,Duplicates,Counter,我试图通过创建一个临时数组来删除列表中的重复项,该数组存储重复项所在位置的索引,然后将原始数组复制到另一个临时数组中,同时将索引与我在第一个临时数组中存储的索引进行比较 public void removeDuplicates() { double tempa [] = new double [items.length]; int counter = 0; for ( int i = 0; i< numItems ; i++) { for(i

我试图通过创建一个临时数组来删除列表中的重复项,该数组存储重复项所在位置的索引,然后将原始数组复制到另一个临时数组中,同时将索引与我在第一个临时数组中存储的索引进行比较

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

我不明白计数器怎么会超过items.length的值,逻辑缺陷在哪里?

您已经使用
num\u items
来绑定循环。也可以使用该变量设置tempa的数组大小

double tempa [] = new double [num_items];

假设这是您的输入数据:

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循环不会阻止您尝试插入重复数组索引的副本

最好的解决方案是什么

使用一套 集合保证其中没有重复的条目。如果创建一个新集合,然后将所有数组项添加到其中,该集合将删除重复项。然后,它只是从集合返回到数组的问题

或者,这里有一个非常简单的方法来做同样的事情:

//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
            }
        }
    }
}
//duplicates将是一个真值表,指示哪些索引是重复的。
//最初,所有值都设置为false
布尔值重复项[]=新布尔值[items.length];
对于(int i=0;i

我让你自己想办法完成。

你把事情弄得很困难。让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));
double[]输入={1,2,3,3,4,4};
Set tmp=newlinkedhashset();
for(每双:输入){
tmp.添加(每个);
}
double[]输出=新的double[tmp.size()];
int i=0;
适用于(双份:tmp){
输出[i++]=每个;
}
System.out.println(Arrays.toString(output));

您可以简单地使用
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[]{});
}
publicstaticvoidmain(字符串[]args)
{
Double[]值=新的Double[]{1.0,2.0,2.0,2.0,3.0,10.0,10.0};
Set singleValues=new HashSet();
for(双值:值)
{
singleValues.add(value);
}
System.out.println(“singleValues:+singleValues”);
//现在将其转换为双数组
Double[]dValues=singleValues.toArray(新的Double[]{});
}

这里是另一个不使用集合的替代方案,仅使用基元类型:

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);
}
publicstaticdouble[]删除的副本(doublearr[]){
double[]tempa=新的double[arr.length];
int uniqueCount=0;

对于(int i=0;i您可以使用一个集合来删除倍数。

对于int数组完成,但是可以很容易地转换为double

1) 如果您不关心初始数组元素顺序:

private static int[] withoutDuplicates(int[] a) {
    Arrays.sort(a);
    int hi = a.length - 1;
    int[] result = new int[a.length];
    int j = 0;
    for (int i = 0; i < hi; i++) {
        if (a[i] == a[i+1]) {
            continue;
        }
        result[j] = a[i];
        j++;            
    }
    result[j++] = a[hi];
    return Arrays.copyOf(result, j);
}
private static int[] withoutDuplicates2(int[] a) {
    HashSet<Integer> keys = new HashSet<Integer>();
    int[] result = new int[a.length];
    int j = 0;
    for (int i = 0 ; i < a.length; i++) {
        if (keys.add(a[i])) {
            result[j] = a[i];
            j++;
        }
    }
    return Arrays.copyOf(result, j);
}
private static Object[] withoutDuplicates3(int[] a) {
    HashSet<Integer> keys = new HashSet<Integer>();
    for (int value : a) {
        keys.add(value);
    }
    return keys.toArray();
}
private static int[]不带重复项(int[]a){
数组。排序(a);
int hi=a.长度-1;
int[]结果=新的int[a.length];
int j=0;
对于(int i=0;i
2) 如果您关心初始数组元素顺序:

private static int[] withoutDuplicates(int[] a) {
    Arrays.sort(a);
    int hi = a.length - 1;
    int[] result = new int[a.length];
    int j = 0;
    for (int i = 0; i < hi; i++) {
        if (a[i] == a[i+1]) {
            continue;
        }
        result[j] = a[i];
        j++;            
    }
    result[j++] = a[hi];
    return Arrays.copyOf(result, j);
}
private static int[] withoutDuplicates2(int[] a) {
    HashSet<Integer> keys = new HashSet<Integer>();
    int[] result = new int[a.length];
    int j = 0;
    for (int i = 0 ; i < a.length; i++) {
        if (keys.add(a[i])) {
            result[j] = a[i];
            j++;
        }
    }
    return Arrays.copyOf(result, j);
}
private static Object[] withoutDuplicates3(int[] a) {
    HashSet<Integer> keys = new HashSet<Integer>();
    for (int value : a) {
        keys.add(value);
    }
    return keys.toArray();
}
private static int[]without duplicates2(int[]a){
HashSet keys=新的HashSet();
int[]结果=新的int[a.length];
int j=0;
for(int i=0;i
3) 如果您不关心初始数组元素顺序:

private static int[] withoutDuplicates(int[] a) {
    Arrays.sort(a);
    int hi = a.length - 1;
    int[] result = new int[a.length];
    int j = 0;
    for (int i = 0; i < hi; i++) {
        if (a[i] == a[i+1]) {
            continue;
        }
        result[j] = a[i];
        j++;            
    }
    result[j++] = a[hi];
    return Arrays.copyOf(result, j);
}
private static int[] withoutDuplicates2(int[] a) {
    HashSet<Integer> keys = new HashSet<Integer>();
    int[] result = new int[a.length];
    int j = 0;
    for (int i = 0 ; i < a.length; i++) {
        if (keys.add(a[i])) {
            result[j] = a[i];
            j++;
        }
    }
    return Arrays.copyOf(result, j);
}
private static Object[] withoutDuplicates3(int[] a) {
    HashSet<Integer> keys = new HashSet<Integer>();
    for (int value : a) {
        keys.add(value);
    }
    return keys.toArray();
}
private static Object[]without duplicates3(int[]a){
HashSet keys=新的HashSet();
for(int值:a){
增加(价值);
}
返回键。toArray();
}
导入java.util.HashSet;
导入sun.security.util.Length;
公共类数组复制{
公共静态void main(字符串[]args){
int arr[]={1,5,1,2,5,2,10};
TreeSetset=newtreeset();

对于(int i=0;ii如果您提供了异常的堆栈跟踪,那么回答您的问题就会容易得多。
numItems
是如何定义的?它从何处获取其值?您也没有检查
tempa
数组中是否已经存在索引,这允许对每个重复numit将计数器提前两次ems只是数组副本的大小!哦,天哪!哈希集保留排序吗?不,它没有。如果你需要排序,你可以在排序后进行排序。什么?好的,这就是计数器给出错误的原因,让我想一想,因为我还没有完全理解它关于集合的内容-我想这样做,但我必须掌握这个删除Edupplicate首先实现一个集合类。不需要实现集合,Java库有很多可供您使用。请参见Adam的答案中的一个示例。我还为您提供了一个正确识别重复项的替代方案,因此现在只需找出如何生成唯一项数组。我很想,但我对语言和结构有限,希望先把逻辑写下来。@user1702633如果你满意这个答案,你能接受吗