2

I'm trying to print the value of z as output but My code doesn't finish execution..it reaches the line "here" but never reachs the last line "z is ".

i'm guessing s = sc.nextInt(); is the problem.

public class Solution {

public static void main(String[] args) {

    Scanner sc=new Scanner(System.in);
    int x = 0;
    int y = 0;
    int z = 0;
    int u = 0;
    int n = sc.nextInt();
    int s = sc.nextInt();
    while(sc.hasNextInt()) {
        if(s != -1){
            y = s;
            if(sc.hasNextInt()){
                s = sc.nextInt();                 
            }
        }     
        while(s == -1){
            x++;
            System.out.println("s is "+s);
            z = Math.abs(y - x) + u;
            System.out.println("s is "+s);
            System.out.println("x is " + x+ " y is "+ y+" z is "+z);
            if(sc.hasNextInt()){
                s = sc.nextInt();                 
                System.out.println("s33 is "+s);
            }
        }
        if(z != 0){
            u = z;
        }    
        x = 0;
        y = 0;
        System.out.println("here");
    }
    System.out.println("z is" +z);
    }
}

Thanks.

Ahmad Fahmy
  • 327
  • 1
  • 2
  • 11
  • 1
    Did you debug this? Since you have two loops, I would guess there is an infinite loop here. But this could be stuck on the Scanner too. Or both ^^ – AxelH Dec 30 '16 at 12:39
  • calling then `nextInt()` function instead of storing the values in variables before is not a good idea....at every `nextInt()` statement, the program expects you to enter an integer. – progyammer Dec 30 '16 at 12:40
  • 3
    Possible duplicate of [Java Scanner hasNext() doesn't return false](http://stackoverflow.com/questions/15847036/java-scanner-hasnext-doesnt-return-false) – AxelH Dec 30 '16 at 12:41
  • yes i debugged it thats why there is alot of print statements @AxelH – Ahmad Fahmy Dec 30 '16 at 13:50
  • i don't understand what u mean by storing it before i'm storing it in s..i'm kinda beginner so thanks for u two @progy_rock – Ahmad Fahmy Dec 30 '16 at 13:52

2 Answers2

1

Its not going in infinite loop but instead you already have two values stored in Scanner which you are checking with hasNextInt(). Hence its always true and waits for next input to check. If you go with entering Int values it will be in same while loop. Enter non-integer like String to go out of while loop and your program will end. Actually You are waiting for input in both while loops and hence its waiting for your input.

Rahul Deore
  • 37
  • 1
  • 11
  • i'm kinda beginner here so i'm not sure i completely understand you..how is hasNextInt() always true it shouldn't be true when i reach the last 1 in input like this "3 -1 -1 1"?..thanks for ur answer – Ahmad Fahmy Dec 30 '16 at 14:03
0

Problem

You are using a Scanner on the system input stream System.in. That means sc.hasNextInt() tries to get the next value from the underlying stream, which is System.in. However, this stream will just prompt you for new input and return it to the Scanner. Once the Scanner receives a newline character, it checks, if the sequence before is an int or not. In case you only hit enter, the sequence is empty, hence ignored. It is not the loop that is indefinitely executed if you hit enter repeatedly, your code is stuck at sc.hasNextInt(), which gets no new token (because of the empty sequence), and asks the underlying stream again and again.

However, if you enter anything but an int, like 0.2 or abc... the Scanner will return false, as the sequence is not empty and not an int.

Solution

If you want to keep your code as it is and you want that hasNextInt() returns false when you hit enter (only newline), you can wrap your Scanner in this wrapper:

import java.util.Scanner;

public class ScannerWrapper {

    private Scanner scanner;
    private Integer current;

    public ScannerWrapper(Scanner scanner) {
        this.scanner = scanner;
    }

    public boolean hasNextInt() {

        // Current is not null, if method is called multiple
        // times, the value was checked already, it is an integer
        if (current != null) {
            return true;
        } else {

            // Reads line including newline character
            String nextLine = scanner.nextLine();

            try {
                // Try to covert the input to an integer
                current = Integer.parseInt(nextLine);
                return true;
            } catch (NumberFormatException e) {
                // Input is not an integer
                return false;
            }

        }
    }

    public int nextInt() {

        // Used the already checked value or request new input
        if (current != null) {
            int next = current;
            current = null;
            return next;
        } else {

            int next = scanner.nextInt();

            // Consume the newline character
            scanner.nextLine();

            return next;

        }
    }

}

This class reads complete lines and converts them into int, if possible. As you cannot push back the last token you have read with a Scanner, this class stores it temporarily, so multiple calls to hasNextInt() do not skip values. In your method just add:

public static void main(String[] args) {

    Scanner scanner = new Scanner(System.in);
    ScannerWrapper sc = new ScannerWrapper(scanner);

    int x = 0;
    // Rest of your code...

}
thatguy
  • 21,059
  • 6
  • 30
  • 40
  • i'm starting to get it..should i change the first while loop to while(d < n "which is the number of coming integers in the input") and then increment d++ after every call to nextInt()? i already tried it but also stuck in the while loop so i want to know if i'm thinking right..thanks for ur time – Ahmad Fahmy Dec 30 '16 at 15:16
  • it's a problem on code forces http://codeforces.com/contest/427/problem/A for every positive integer i should count how many -1 come after it and compare it with the positive integer – Ahmad Fahmy Dec 30 '16 at 16:25
  • the z in code gives the right value for test cases..i just want to get it out of the loop :D – Ahmad Fahmy Dec 30 '16 at 16:28
  • To be clear, you want the scanner to return `false`, if you **press enter** or any other type than `int` is supplied (the latter is done already)? – thatguy Dec 30 '16 at 16:34
  • I have added a solution. However, your project can be solved far easier by reading two lines, the first for `n`, the second as in the link. Then you can split the latter string up and loop over it. – thatguy Dec 30 '16 at 16:54
  • when i add this line ScannerWrapper sc = new ScannerWrapper(scanner); i get this error cannot find symbol symbol: class ScannerWrapper – Ahmad Fahmy Dec 30 '16 at 17:15
  • i also doubt how i can solve it with split..i can split it every "-" but i don't only need to know the number of "-" i need to know it's position – Ahmad Fahmy Dec 30 '16 at 17:24
  • 1.) That means the class `ScannerWrapper` is not found. Did you put the code for `ScannerWrapper` in a sperate file _ScannerWrapper.java_ in **the same folder** as your class `Solution`? If you used another folder, you have to add an `import` statement. If that does not work, there is most likely a spelling error. 2.) You can easily solve it like that, split by whitespace, parse each token, `n` is the amount of tokens, done. – thatguy Dec 30 '16 at 17:33
  • i didn't realize it was space separated untill you told me..i did it ur way still it's hard for me and doesn't pass all tests..thanks for ur help anyway :) – Ahmad Fahmy Dec 31 '16 at 10:47