4

I am trying to figure out how to remove leading zeros from an array. The array is currently stored with the least significant bit at the first position.

Example: if number is 1101 it is stored in my array as: [1,1,0,1]. I do not want to flip the array or change it in anyway except remove the leading zeros. I have the bolded the leading zero that needs to be removed.

I am trying to just do this with just using the array and not converting it

Ex: current output : 0 1 1 0

Expected output: 0 1 1

public static byte[] normal(byte[] arr)
    {
        //check if all the numbers are 0 and last is 1
        byte [] output = new byte[copy.length];
        for(int i = arr.length;i<=0;i--)
        {
            if(arr[i]==1){          
                output[i]=copy[i];
            }

        }
        return output; 

    }
Mureinik
  • 297,002
  • 52
  • 306
  • 350
jim
  • 117
  • 2
  • 7

4 Answers4

3

Your problem is that the output array is the same size as the input array... the 0s that you skip are still going to be there because 0 is the default value of any item in an int[].

So, I would start at the end of your input array, and not actually initialize the output array until you hit the first 1. Then you know how big to make the output array.

public static byte[] normal(byte[] arr) {
    byte[] output = null;
    System.out.println(arr.length);
    for (int i = arr.length-1; i >= 0; i--) {
        if (arr[i] != 0) {
            if (output == null) {
                output = new byte[i+1];
            }
            output[i] = arr[i];
        }
    }

    if (output == null) { // cover case where input is all 0s
        output = new byte[0];
    }

    return output;
}
dcsohl
  • 7,186
  • 1
  • 26
  • 44
2

Iterate backwards over the array and find the index of the last occuring 1 (or you reach the front of the array). Then copy the array up to and including that index. Because you know the index of the final array, you know how large the returned array will have to be (size lastIndex + 1)

It's been a while since I've written java code, so this might not compile or run properly. But the code for this might look like this:

public static byte[] normal(byte[] arr)
{
    //null check arr if desired

    int indexOfLastNonZero = arr.length - 1;
    boolean foundOne = false;
    while(!foundOne && indexOfLastNonZero >= 0)
    {
        if (arr[indexOfLastNonZero] == (byte) 1)
            foundOne = true;
        else
            indexOfLastNonZero -= 1;
    }

    if (foundOne) 
    {
        byte[] output = new byte[indexOfLastNonZero + 1];
        System.arraycopy( arr, 0, output, 0, output.length );
        return output;
    }
    else 
    {
        return null; //or size 0 array if you prefer
    }
}
ryanyuyu
  • 6,366
  • 10
  • 48
  • 53
2

Your output array is too long. First you should count how many leading zeroes you have, and create an output array shorter than arr but that many elements:

public static byte[] normal(byte[] arr)
{
    // Count the leading zeros:
    int zeroes = 0;
    while (arr[zeroes] == 0) {
        ++zeroes;
    }

    //check if all the numbers are 0 and last is 1
    byte[] output = new byte[arr.length - zeroes];
    for(int i = output.length - 1; i >= 0; ++i) {
        output[i] = arr[i - zeroes]; 
    }
    return output; 
}

Or better yet, use the built-in Arrays.copyOfRange:

public static byte[] normal(byte[] arr)
{
    // Count the leading zeros:
    int zeroes = 0;
    while (arr[zeroes] == 0) {
        ++zeroes;
    }

    //check if all the numbers are 0 and last is 1        
    return Arrays.copyOfRange(zeroes, arr.length); 
}
Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • 1
    This is counting zeroes on the left, and OP has stated that leading zeroes are on the right. – fps Aug 28 '15 at 19:51
1

I suggest to count the number of continuous zeros from the last and then generate the output array which will be of the count size lesser than that the original size...

public static byte[] normal(byte[] arr)
    {
        int count = 0;

        for(int i = arr.length-1;i>=0;i--)
        {

            if(arr[i]==1){          
                break;
            }
            count++;
        }

        byte [] output = new byte[copy.length-count];
        for(int i = 0;i<(copy.length-count);i++) {
            output[i] = copy[i];
        }
        return output; 
    }
burglarhobbit
  • 1,860
  • 2
  • 17
  • 32
  • This solution is OK, but you have a bounds issue in the first `for`. Change it to `for (int i = arr.length - 1; i >= 0; i--)`. – fps Aug 28 '15 at 19:57
  • Yes. Thank you for noticing. Edited. – burglarhobbit Aug 28 '15 at 20:00
  • @Mr.Robot quick question: lets say my output is 0. If the output is just zero I do want to display that- how could I create a test for that? For example if the number is 00. I only want to display 0- how can i test for that? – jim Aug 29 '15 at 17:37
  • For that, you have to add an extra condtion after the end of the first `for loop` that `if(count==arr.length)` then create a `byte[] output` of size 1 and assign it's value to _zero_ or `else` `byte[] output = new byte[blahblah] for(blahblah) { output[i] = copy[i]; }` – burglarhobbit Aug 29 '15 at 17:51