从数组中删除重复项(没有集合或排序)

时间:2014-10-25 22:57:34

标签: java arrays duplicates duplicate-removal

我有以下代码:

import java.util.Scanner;
public class ArrayDuplicates {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        System.out.print("How many numbers are you going to enter? ");
        int num = scan.nextInt();
        int[] arr = new int[num]; // initialize array with user inputted length
        for (int i = 0; i < arr.length; i++) { // enter numbers into array
            arr[i] = scan.nextInt();
        }

        int[] unique = new int[arr.length];    //initialize new array that will hold unique values
        for (int i = 0; i < arr.length; i++) {
            boolean b = true;    //boolean that checks if an element is a duplicate
            for (int j = i+1; j < arr.length; j++) {    //check all elements above int i
                if (arr[i] == arr[j]) {
                    b = false;    // set b to false if there is an existing duplicate
                }
            }
            if (b) {
                unique[i] = arr[i];    // if no duplicates exist, then it is unique.
            }
        }   
        for (int i = 0; i < unique.length; i++) {
                System.out.println(unique[i]);
        }
    }
}

此代码的问题(除了对大型数组来说非常慢,但这不是重点)是因为unique数组的未声明元素将设置为0,所以副本来自第一个数组的元素被设置为0中的unique[](如果这有意义的话)。我理解为什么会发生这种情况,但无法找到解决此问题的有效方法。我尝试将复制元素设置为唯一数组中的Integer.MIN_VALUE,然后仅打印unique[]不等于Integer.MIN_VALUE的元素,但这似乎是问题的弱解决方案。我该如何解决这个问题?

编辑:如果我运行代码:

  

你要输入多少个号码? 4
  1
  2
  2
  0

输出:

1
0
2
0

由于数组的第二个元素是重复的,我没有将unique[1]设置为任何值,使其默认为0.如何避免打印0,因为它不是原始数组的一部分?

编辑2:是的,这是作业,但我不想使用集合,排序等的原因主要是我不熟悉它们。另外,由于我不是要求任何人为我编写整个程序,我认为可以请求一些帮助。

10 个答案:

答案 0 :(得分:4)

您选择的任何值(零,min-int,max-int)表示删除的副本是个问题。用户总是可以输入该号码,并且您的程序将无法正常运行。 (你可以合法地使用(例如)min-int或max-int的唯一方法是,如果要求明确表示该数字是无效输入。)

处理重复项的正确方法是保留非重复项数量的计数器,并确保重复项(或包含它们的插槽)位于数组的高端;即索引&gt; =计数器。 (这将成为您的算法需要维护的不变量......)

最佳解决方案是在将重复项添加到阵列之前消除重复项。保持非重复数量的计数并迭代,直到达到num ...而不是数组的长度。

但是如果你确实想要将所有值添加到数组中并且然后消除重复项,那么当找到重复项时,您需要交换元素以便可以保持不变量。逻辑有点繁琐......但非常可行。

<强>更新

我刚注意到你的原始解决方案是使用两个数组。我假设您使用的是一个数组,并进行就地更新以消除重复数据。

答案 1 :(得分:3)

我将使用您用来解决问题的工具,因为我的一些事情告诉我这是作业......

import java.util.Scanner;

public class ArrayDuplicates 
{

   public static void main(String[] args) 
   {

      Scanner scan = new Scanner(System.in);

      System.out.print("How many numbers are you going to enter? ");
      int num = scan.nextInt();

      int[] arr = new int[num]; // initialize array with user inputted length

      for (int i = 0; i < arr.length; i++)// enter numbers into array
      {

         arr[i] = scan.nextInt();

      }

      double[] unique = new double[arr.length];    //initialize new array that will hold unique values

      ///////My edit

      for(int z = 0; z < unique.length; z++)
      {

         unique[z] = -0.5;

      }

      ///////

      for (int i = 0; i < arr.length; i++) 
      {

         boolean b = true;    //boolean that checks if an element is a duplicate

         for (int j = i+1; j < arr.length; j++)    //check all elements above int i
         {

            if (arr[i] == arr[j]) 
            {

               b = false;    // set b to false if there is an existing duplicate

            }

         }

         if (b) 
         {

            unique[i] = arr[i];    // if no duplicates exist, then it is unique.

         }

      }   

      for (int i = 0; i < unique.length; i++) 
      {

         if(!(unique[i] == -0.5))
         {

            System.out.println((int)(unique[i]));

         }

      }

   }
}

那么,你看到我在哪里注释了我的编辑?这是新事物,一种非常简单的检查方法是给出一个预期的数字,在这种情况下是一个负数。现在,这是我的一个假设,将-1改为你知道输入Scanner的任何值。 if语句也是如此。

答案 2 :(得分:2)

执行此操作的最佳方法是使用Map

public interface Map<K,V>
  

将键映射到值的对象。地图不能包含重复内容   键;每个键最多可以映射一个值。

我不知道为什么你不想使用一套,除非你正在做作业......


如果你真的不能使用套装。继续创建ArrayList。将array的元素存储在内部,但每次要存储时,请检查该元素是否已经是ArrayList的一部分。

 int [] list = {5, 5, 3, 2, 5, 3, 5};

 ArrayList<Integer> list2 = new ArrayList<Integer>();

 for(int i = 0; i < list.length; i++)
    if(!list2.contains(list[i]))
        list2.add(list[i]);

如果需要,您可以将ArrayList转回数组。

Object[] list3 = list2.toArray();

答案 3 :(得分:1)

您可以存储用户输入的最大值(当用户在第一个循环中输入值时),然后将unique的默认值等于max + 1.

或者您可以尝试其他方法来解决问题,如下所示:

  int num = scan.nextInt();
  int[] arr = new int[num];
  int[] uniq = new int[num+1000000];
  int j = 0;

  // enter numbers into array
  for (int i = 0; i < arr.length; i++) { 
     int input = scan.nextInt(); 
     if(uniq[input] != 1){
         uniq[input] = 1;  
         arr[j] = input;
         j++;
      }
   } 

   for (int i = 0; i < j; i++) {
      System.out.println(arr[i]);
   }

请注意,此解决方案假设用户不会输入大于(num + 1,000,000)的数字。

答案 4 :(得分:1)

此解决方案允许您输入任何整数值,甚至是负数。它是相同的代码并进行了一些修改,并添加了一个并行数组进行比较。它还删除了一些不再需要的代码行。

public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    System.out.print("How many numbers are you going to enter? ");
    int num = scan.nextInt();
    int[] arr = new int[num]; // initialize array with user inputted length
    int[] arrflag = new int[num];
    for (int i = 0; i < arr.length; i++) { // enter numbers into array
        System.out.print("Enter number: ");
        arr[i] = scan.nextInt();
        arrflag[i] = 0;
    }

    int[] unique = new int[arr.length];    //initialize new array that will hold unique values
    int n=0;
    for (int i = 0; i < arr.length; i++) {            
        if (arrflag[i] == 0) {
            unique[n++] = arr[i];
            for (int j = i+1; j < arr.length; j++) {    //check all elements above int i
                if (arr[i] == arr[j]) {                        
                    arrflag[j]=-1;
                }
            }                
        }
    }   
    for (int i = 0; i < n; i++) {
            System.out.println(unique[i]);
    }
}

答案 5 :(得分:0)

创建一个并行字符数组,其中所有值都为“。”每当找到重复项时,请在字符数组中将值设置为“,”。然后仅打印具有相应“。”的数组值。在字符数组中。

 }
    System.out.println();
    for (int i = 0; i < arr.length; i++) {
        if(a[i]=='.')
            System.out.println(arr[i]);
    }
}

}

答案 6 :(得分:0)

String []的示例。

public static List<String> arrListWithNoDups(String arr[]){

    Map<String, Integer>map = new HashMap<String, Integer>();
    List<String>list = new ArrayList<String>();

    for(int i = 0; i<arr.length; i++){
        if(map.get(arr[i]) == null){
            map.put(arr[i], 0);
        }
        else{
            map.put(arr[i], map.get(arr[i])+1);
        }
    }

    for(int j = 0; j<arr.length; j++){
        if(map.get(arr[j])==0){
            list.add(arr[j]);
        }
    }

    return list;

}

答案 7 :(得分:0)

公共类RemoveDuplicateFromArray {

public static void main(String[] args) {

    int[] myArray = {1, 2, 1, 4, 1, 5, 2, 5};
    System.out.println("Before removing duplicate" + Arrays.toString(myArray));

    RemoveDuplicateFromArray rd = new RemoveDuplicateFromArray();
    int[] newArray = rd.findDuplicate(myArray);
    System.out.println("Before removing duplicate" + Arrays.toString(newArray));
}

public int[] findDuplicate(int[] inputArray) {
    Arrays.sort(inputArray);
    int count = 0;
    for (int i = 0; i < inputArray.length; i++) {
        if (i + 1 < inputArray.length && inputArray[i] == inputArray[i + 1]) {
            count++;
        }
    }
    int[] result = new int[inputArray.length - count];
    int c = 0;
    for (int j = 0; j < inputArray.length; j++) {
        if (j + 1 < inputArray.length && inputArray[j] == inputArray[j + 1]) {

        } else {
            result[c] = inputArray[j];
            c++;
        }
    }
    inputArray = result;
    return inputArray;
}

}

答案 8 :(得分:0)

我试图改进此代码,如果可以进一步改进,请发表评论/建议。

public static int[] removeDuplicate(int[] arr) {
    int[] noDuplicates = new int[arr.length];
    for (int i = 0; i < arr.length; i++) {
        boolean b = true;

        for (int j = i + 1; j < arr.length; j++) {
            if (arr[i] == arr[j]){
                b = false;
            }
        }

        if (b) {
            noDuplicates[i] = arr[i];
            System.out.print(noDuplicates[i] + " ");
        }
    }
    return noDuplicates;

}

答案 9 :(得分:-2)

void myFunction(int arr[])
{

    int size=arr.length;
    for(int i=0;i<size;i++)
    {
        for(int j=i+1;j<size;j++)
        {

            if(arr[i]==arr[j])
            {
                arr[j]=arr[size-1];
                size--;
            }
        }
    }

    for(int a=0;a<size;a++)
    {
        System.out.print(arr[a]+" ");
    }

}