1

I was trying to solve the following question in java .

Maya buys “N” no of products from a shop. The shop offers a different percentage of discount on each item. She wants to know the item that has the minimum discount offer, so that she can avoid buying that and save money.

[Input Format: The first input refers to the no of items; the second input is the item name, price and discount percentage separated by comma(,)]

Assume the minimum discount offer is in the form of Integer.

Note: There can be more than one product with a minimum discount.

Sample Input 1:

4

mobile,10000,20

shoe,5000,10

watch,6000,15

laptop,35000,5

Sample Output 1:

shoe

Explanation: the discount on the mobile is 2000, the discount on the shoe is 500, the discount on the watch is 900 and the discount on the laptop is 1750. So the discount on the shoe is the minimum.

I got this error in my code .but everthing is looking good so I coundn't able to find the bug.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2 at Main.main(Main.java:24)

The error is in the following code block.

    for(int i=0;i<n;i++)
     {
         discount[i]=(Integer.parseInt(input1[i][2])*Integer.parseInt(input1[i][1]))/100;  
     }

Here is the Full code.

    import java.util.*;
    
    public class Main 
    {
        public static void main(String[] args)
        {
            Scanner sc=new Scanner(System.in);
            int n;
            n=sc.nextInt();
            
            String input[]=new String[n];
            String input1[][]=new String[n][3];
            
            for(int i=0;i<n;i++)
            {
                input[i]=sc.nextLine();
                input1[i]=input[i].split(",");
            }
            
            int discount[]=new int[n];
            
            for(int i=0;i<n;i++)
            {
                discount[i]=(Integer.parseInt(input1[i][2])*Integer.parseInt(input1[i][1]))/100;  
            }
    
            int min_d=32767; //highest value that int can store;
             for(int i=0;i<n;i++)
            {
                if(min_d>discount[i])
                min_d=discount[i];
            }
    
            String output=new String();
    
            for(int i=0;i<n;i++)
            {
                if(discount[i]==min_d)
                output+=input1[i][0]+" ";
            }
    
            System.out.println(output);
    
        }
    }
ShubhWIP
  • 766
  • 1
  • 5
  • 18
  • java.lang.ArrayIndexOutOfBoundsException: 2 means you are trying to get the third element of an array that contains (maximum) two elements. – Stultuske Feb 08 '21 at 07:40
  • To add to that, you must be trying to read a line that does not have three elements in it. – jr593 Feb 08 '21 at 07:41
  • @Stultuske I tried it by giving sample input as custom input but still got the same error. – rohith reddy Feb 08 '21 at 07:45
  • changing the input won't remove the issue. the issue is you don't check whether something exists before trying to get it. the problem is not in your input, it's in your implementation – Stultuske Feb 08 '21 at 07:46
  • @Stultuske That was useful information , thanks alot for trying to help . I got the solution (in answers ) by " ShubhWIP ". the solution is to add sc.nextLine() in the next line of sc.nextInt() – rohith reddy Feb 08 '21 at 08:23

3 Answers3

2

By debugging your program I found that When I give input to your program like this

Input :

4
mobile,10000,20
shoe,5000,10
watch,6000,15
laptop,35000,5

Your input1 array is looking like this

input1 = {String[4][]@906} 
 0 = {String[1]@909} 
  0 = ""
 1 = {String[3]@917} 
  0 = "mobile"
  1 = "10000"
  2 = "20"
 2 = {String[3]@918} 
  0 = "shoe"
  1 = "5000"
  2 = "10"
 3 = {String[3]@919} 
  0 = "watch"
  1 = "6000"
  2 = "15"

It has missed laptop input i.e 4th one and first element is being the empty string.

It is because Scanner.nextInt method does not read the newline character in your input created by hitting "Enter," and so the call to Scanner.nextLine returns after reading that newline.

Reference : Scanner is skipping nextLine() after using next() or nextFoo()?

I am updating the code here with single line addition of sc.nextLine()

import java.util.Scanner;

public class Test {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n;
        n = sc.nextInt();
        sc.nextLine();
        String input[] = new String[n];
        String input1[][] = new String[n][3];

        for (int i = 0; i < n; i++) {
            input[i] = sc.nextLine();
            input1[i] = input[i].split(",");
        }

        int discount[] = new int[n];

        for (int i = 0; i < n; i++) {
            discount[i] = (Integer.parseInt(input1[i][2]) * Integer.parseInt(input1[i][1])) / 100;
        }

        int min_d = 32767; //highest value that int can store;
        for (int i = 0; i < n; i++) {
            if (min_d > discount[i])
                min_d = discount[i];
        }

        String output = new String();

        for (int i = 0; i < n; i++) {
            if (discount[i] == min_d)
                output += input1[i][0] + " ";
        }

        System.out.println(output);

    }
}

Output:

4
mobile,10000,20
shoe,5000,10
watch,6000,15
laptop,35000,5
shoe 
ShubhWIP
  • 766
  • 1
  • 5
  • 18
0

In this line

input1[i]=input[i].split(",");

You are overriding the initialization you made in this line:

String input1[][]=new String[n][3];

So even at first you initialized input[i] with array of size 3, you override it with the value returned from calling the split function, which probably retrieved a less than 3 length array value.

javadev
  • 532
  • 3
  • 16
0

By quick check your code, it seems your input1 array is re-initialising with wrong value you expected:

        for(int i=0;i<n;i++)
        {
            input[i]=sc.nextLine();
            input1[i]=input[i].split(",");
        }

Check your input what you are taking, add a print method to check your input, and add another print method to recheck input after re-initialising:

        for(int i=0;i<n;i++)
        {
            input[i]=sc.nextLine();
            System.out.println(Arrays.toString(input[i]));
            input1[i]=input[i].split(",");
            System.out.println(Arrays.toString(input[i]));
        }

if everything goes well, then continue with your logic.