0

I have a task to return an array of those numbers that end in 9. Do not change the order of the remaining numbers. The only thing I can use is a for loop.

My brain is kinda melted at the moment and I don't know what to do.

When I return a result, it returns as an int 3991599399.

At the moment I think about how to take the result outside the for loop. Сan you help me find a way to store all numbers with nines in a new array?

    
public int[] leavePrice9(int[] prices) {
        
    for (int i = 0; i < prices.length; i++) {
            int result = prices[i];
            
            if (result % 10 == 9);
    }
}
    public static void main(String[] args) {
        QuadraticEquationSolver shop = new QuadraticEquationSolver();

        //Should be [399, 1599, 399]
        int[] prices = new int[] {399, 1599, 399, 50, 10, 10, 70};
        System.out.println(Arrays.toString(shop.leavePrice9(prices)));
    }
}

Johannes Kuhn
  • 14,778
  • 4
  • 49
  • 73
  • 1
    Please clarify your task. You want a method that takes an `int[]` and returns a new `int[]` of values that end in `9`; correct? What are "remaining numbers"? Also, can you use a collection like a `List` temporarily? – Elliott Frisch Apr 23 '22 at 14:46
  • Yes, my apologies, I've changed the code to the correct one, the previous was in my draft, the only thing I can use is a for loop @ElliottFrisch – Orest Dymarchuk Apr 23 '22 at 14:56
  • 1
    Right away, I see two problems with the code: 1) `leavePrice9(int[] prices)' is declared to return `int []`, but is missing a `return` statement. 2) `if (result % 10 == 9);' doesn't do anything. `if (result % 10 == 9);' should have one statement before the `;` or be followed by a block, i.e., `{ ... }`, where `...` is one or more statements – Old Dog Programmer Apr 23 '22 at 16:34
  • 1
    AFAICT, the question is poorly worded. My interpretation is "Given an array of `int`, how can I return a subarray of only those elements that have a certain property?" – Old Dog Programmer Apr 23 '22 at 17:27
  • 2
    `IntStream.of(arr).filter(i -> i % 10 == 9).toArray()` – Johannes Kuhn Apr 23 '22 at 17:33
  • 1
    I understand your complaint @James, first I used code from my drafts here, it had System.out.print, then I changed to the moment when I got stuck. – Orest Dymarchuk Apr 23 '22 at 20:08

2 Answers2

4

You can use the following method getAllWithLastDigit(). It takes an array of int and a digit (0-9) and returns a new array containing all elements that have that specified digit as the last digit. The elements of the original array remain untouched and therefore the order is obviously preserved.

import java.util.*;

public class Application {
    public static void main(String[] args) {
        int[] prices = new int[]{399, 1599, 399, 50, 10, 10, 70};
        System.out.println(Arrays.toString(getAllWithLastDigit(prices, 9)));
    }

    public static int[] getAllWithLastDigit(int[] array, int lastDigit){
        if(lastDigit < 0 || lastDigit > 9) throw new IllegalArgumentException("lastDigit must be between 0 and 9!");
        var lst = new ArrayList<Integer>();
        for (int i = 0; i < array.length; i++) {
            int result = array[i];
            if (result % 10 == lastDigit) lst.add(result);
        }
        // convert array list back to integer array
        return lst.stream().mapToInt(i -> i).toArray();
    }
}

Expected ouput:

[399, 1599, 399]

This uses an ArrayList to be able to dynamically add elements to the list whenever we encounter an element that has 9 as the last digit. In the end we need to convert the list back to an array as you want to return an array of integers.

What you did is just string concatenation, instead of doing this we now add the element to a list, convert that list back to an int array and return it. Your implementation misses the part where a new array is created and returned.

Edit

Here a version without using ArrayList. Here we first create an array capable of holding the maximum number of results and add a result to it while increasing a counter for each new element. Then we have to (possibly) shrink the array down so it only contains the number of elements that are actually within the array. For this we create a copy of the array with however many elements we have in our result.

import java.util.*;

public class Application {
    public static void main(String[] args) {
        int[] prices = new int[]{399, 1599, 399, 50, 10, 10, 70};
        System.out.println(Arrays.toString(getAllWithLastDigit(prices, 9)));
    }

    public static int[] getAllWithLastDigit(int[] array, int lastDigit){
        if(lastDigit < 0 || lastDigit > 9) throw new IllegalArgumentException("lastDigit must be between 0 and 9!");
        // create an array which has the same size as the input, this way we guarantee that we have enough space for all result
        int[] elements = new int[array.length];
        // counter of how many elements are in the array 
        int counter = 0;
        for (int i = 0; i < array.length; i++) {
            int result = array[i];
            if (result % 10 == lastDigit) elements[counter++] = array[i];
        }
        // now we need to create a new array which is exactly as long as we need it (if we don't have that already)
        if(counter == array.length) return elements;
        // Alternative: use Java API Arrays.copyOf(elements, counter)
        return copyArray(array, counter);
    }

    public static int[] copyArray(int[] array, int newLength){
        if(newLength < 0) throw new IllegalArgumentException("Length must not be < 0");
        var copy = new int[newLength];
        // make sure we don't go out of bounds because the new array could be longer than the old one
        var until = Math.min(array.length, newLength);
        // copy over all elements
        for (int i = 0; i < until; i++) {
            copy[i] = array[i];
        }
        return copy;
    }
}
Mushroomator
  • 6,516
  • 1
  • 10
  • 27
  • Hi, thanks for the help, unfortunately, we haven't passed the ArrayList on the courses yet. I'll try to find a way to solve the task by using an additional loop. And of course, I'll check the information regarding the ArrayList. Thanks again :) @Mushroomator – Orest Dymarchuk Apr 23 '22 at 15:06
  • 2
    You can do it with an `int` array as well. The problem is that you would need to know the size of the array beforehand which you don't or you would need to resize the array. Both can be done using an additional loop. This is just a more convenient way using some of the available Java APIs :) – Mushroomator Apr 23 '22 at 15:10
  • 1
    I've now added a possible solution without `ArrayList` – Mushroomator Apr 23 '22 at 15:27
  • I was doing something like this, but there is a mistake somewhere. Your hint regarding Array size is helpful, thank you! @Mushroomator – Orest Dymarchuk Apr 23 '22 at 15:37
  • public int[] leavePrice9(int[] prices) { int first = 0; for (int i = 0; i < prices.length; i++) { int result = prices[i]; if (result % 10 == 9) first++; } int result [] = new int[first]; int index = 0; for (int i = 0; i < prices.length; i++) { int price = prices[i]; if (price % 10 == 9) result[index] = price; } return result; } @Mushroomator – Orest Dymarchuk Apr 23 '22 at 15:38
  • 1
    You're not increasing `index` once you have inserted an element. Your `index` is always `0`, so it only ever modifies the first element in the array. Replace `result[index]` with `result[index++]` and it will work. Notice the [postfix notation](https://stackoverflow.com/questions/5413548/java-prefix-postfix-of-increment-decrement-operators) - this is important here!. – Mushroomator Apr 23 '22 at 15:42
1

Here is a version based on code of the O/P:

public int[] leavePrice9(int[] prices) {
    int count = 0;  // how many prices qualify? 
    int [] result = new int [prices.length]; // hold qualifying prices
    // worst case: every price will qualify.
    // result is large enough to handle worst case
        
    for (int i = 0; i < prices.length; i++) {                               
            if (prices[i] % 10 == 9)
                 result[count++] = prices [i];
    }
    return Arrays.copyOf (result, count);
}
    public static void main(String[] args) {
        QuadraticEquationSolver shop = new QuadraticEquationSolver();

        //Should be [399, 1599, 399]
        int[] prices = new int[] {399, 1599, 399, 50, 10, 10, 70};
        System.out.println(Arrays.toString(shop.leavePrice9(prices)));
    }
}
Old Dog Programmer
  • 901
  • 1
  • 7
  • 9
  • 1
    It would be nice to be able to have **bold** withing `code`. I would like to be able to highlght the changes made to the O/P code. – Old Dog Programmer Apr 23 '22 at 16:41
  • Hello =) I made it with the next code, your's code looks much better than mine. Thank you! @James – Orest Dymarchuk Apr 23 '22 at 20:04
  • 1
    public int[] leavePrice9(int[] prices) { int counter = 0; for (int i = 0; i < prices.length; i++) { int result = prices[i]; if (result % 10 == 9) counter++; } int result [] = new int[counter]; int newCounter = 0; for (int i = 0; i < prices.length; i++) { int price = prices[i]; if (price % 10 == 9) result[newCounter++] = price; } return result; } @James – Orest Dymarchuk Apr 23 '22 at 20:05