[英]How to remove duplicates and matching original elements from list using java
[英]How to remove duplicates from a list using an auxiliary array in Java?
我試圖通過創建一個臨時數組來刪除列表中的重復項,該數組存儲重復項所在的索引,然后將原始數組復制到另一個臨時數組中,同時將索引與我存儲在第一個臨時數組中的索引進行比較。
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的值以上,邏輯缺陷在哪里?
你為自己制造的東西很難。 讓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));
完成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);
}
2)如果你關心初始數組元素的順序:
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);
}
3)如果你不關心初始數組元素的順序:
private static Object[] withoutDuplicates3(int[] a) {
HashSet<Integer> keys = new HashSet<Integer>();
for (int value : a) {
keys.add(value);
}
return keys.toArray();
}
想象一下這是你的輸入數據:
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
}
}
}
}
我留給你弄清楚如何完成。
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);
}
}
您已經使用num_items
來綁定循環。 使用該變量也可以為tempa設置數組大小。
double tempa [] = new double [num_items];
您可以使用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[]{});
}
這是另一種不使用集合的替代方法,只有原始類型:
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);
}
它確實需要一個臨時的雙重對象數組來獲取實際結果。
您可以使用一組來刪除倍數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.