简体   繁体   中英

Java removing zeros from array

I am trying to write a program that will, when executed, will go through an array and remove all instances of 0.0 and change the size of the array equal to the number of non zero elements and put those elements in their previous order. That is, if n=10 and the contents of a[j], j = 0 to n - 1 are initially

0.0, 1.2, 0.0, 0.0, 0.0, 2.3, 0.0, 9.7, 5.6, 0.0

then after execution of the code the contents should be

 n=4, a[0]=1.2, a[1]=2.3, a[2]=9.7, and a[3]=5.6.

This is what I have so far:

import java.util.Scanner;
public class hw2
{
   public static void main(String[] args) 
   {
       Scanner scan = new Scanner(System.in);
       final double KEY = 0.0;
       int n = scan.nextInt();
       double[] a = new double[n];
       for(int i=0; i<n; i++)
       {
           a[i] = scan.nextDouble();
       }
       for(int k = 0; k<n; k++)
       {
           if(a[k] == KEY)
           {
               a[k] = a[k+1];
               n--;
           }
           System.out.println(a[k]);
       }
   }
}

Just a little nudge in the right direction would be appreciated.

Consider using an ArrayList , which will allow you to add items when you want, grow as needed, and maintain an accurate count.

Although in this case, if you wanted/needed to use an array, you could simply not save the value if it's "0", perhaps. (Also don't increment the "used array variable", except when you add, so you know how much contains "non 0" data or treat the first "0" encountered during iteration as "end of useful data" -- arrays are initialized with the default value of the type.)

If you want to go from an array with zeros to an array with no zeros at all, you must use two passes -- one to count the non-zeros, to construct a new array of the appropriate size, and then copy the non-zero values over. This could be done in reverse as well (compact the initial array, and then copy the "filled" portion of it over), but it's slightly more complicated.

If you do continue with your current approach (which the result array will have zeros, but at the end), you need to maintain two index pointers -- one is the primary loop iterator, the second is the next place to put the non-zero value , which is incremented only when a value is copied (or not moved, as when both indexes are the same, which will be the case until the first 0 is encountered). Make sure to "zero" the place you move the non-zero from. The number of moves can be reduced if order does not need to be preserved.

import java.util.Arrays;
import java.util.Scanner;

public class StackOverflow1
{
    public static final double KEY = 0.0;
    private static final Scanner INPUT = new Scanner(System.in);

    public static void main(String[] args) {


       int length = INPUT.nextInt();
       double[] array = new double[length];

       for(int i=0; i<length; i++) {
           array[i] = INPUT.nextDouble();
       }

       int index = 0;
       for(int k = 0; k < length ; k++) {
           if(array[k] == KEY) {
               continue;
           }
           array[index] = array[k]; // bring the non-zeroth element forward
           if (index != k) array[k] = 0; //make the non-zeroth element zero in the actual location
           index++;
       }
       System.out.println("n = " + index + " array = " + Arrays.toString(array));
   }
}

Your implementation (2nd for loop) is not right, it will fail to simple test case: Input > 5 2.0 2 0.0 3 0.0 Your program will have wrong output: 2.0 2.0 3.0 3.0

but it should be 2.0 2.0 3

Also, you can't use == to compare two double.

The following code is my solution basing on your current code:

    public class hw21 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        final double KEY = 0.0;
        final Double ACCEPTABLE_TOLERANCE = 0.000000000001d;

        int n = scan.nextInt();
        double[] a = new double[n];
        for (int i = 0; i < n; i++) {
            a[i] = scan.nextDouble();
        }
        for (int k = 0, j = 0; k < n; k++) {
            if (Math.abs(a[k] - KEY) < ACCEPTABLE_TOLERANCE) {
                continue;
            }
            a[j] = a[k];
            System.out.println(a[j]);
            j++;
        }
    }
}

Also I prefer to use an ArrayList like below:

public class hw2 {
public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    final double KEY = 0.0;
    final Double ACCEPTABLE_TOLERANCE = 0.000000000001d;

    int n = scan.nextInt();
    double[] a = new double[n];
    for (int i = 0; i < n; i++) {
        a[i] = scan.nextDouble();
    }

    List<Double> newList = new ArrayList<Double>();
    for (int k = 0; k < n; k++) {
        if (Math.abs(a[k] - KEY) < ACCEPTABLE_TOLERANCE) {
            continue;
        }
        newList.add(a[k]);
    }

    System.out.println("There are " + newList.size() + " no-zero double:");
        System.out.println(newList);
    }
}

you can remove those unwanted zeros as follows but in this case it get sorted.

@org.junit.Test
public void test15() throws Exception {
    double[] arr = new double[]{0.0,1.1,0.1,0.0,2.1};
    double[] nonZeroArr = arr;

    Arrays.sort(nonZeroArr);
    int index = -1;
    while((index = Arrays.binarySearch(nonZeroArr, 0.0)) > -1){
        double[] newArr = new double[nonZeroArr.length-index-1];
        System.arraycopy(nonZeroArr, index+1, newArr, 0, newArr.length);
        nonZeroArr = newArr;
    }
    for (double d : arr) {
        System.out.print(d +",");
    }
    System.out.println();
    for (double d : nonZeroArr) {
        System.out.print(d + ",");
    }
}

如果您想在课堂上听起来真的很聪明,请指出这是许多语言中唯一的一种,比Java生产力更高:)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM