1

I am fairly new to Java programming, thus facing issues to handle issues such as this. I am writing a program to check if the string input contains at least 2 odd numbers. As part of the problem which I am solving, it asks me to take input for the number of digits my number will have - but that is irrelevant at this point.

I have attempted to traverse through the string and record the first two found odd numbers in a string and then print it. But it seems to fail and I can't understand why.

NB: If the string input is 12272, then it should print 17 as these two are the only odd numbers.

package myPackage;

import java.util.Scanner;

public class Main {
    public static Scanner scanner = new Scanner(System.in);
    public static void main(String[] args) {
        int tc = scanner.nextInt();

        while(true){
            String str="";
            int n = scanner.nextInt();
            String num = scanner.nextLine();
            int cnt = 0;
            for (int i = 0; i < num.length(); i++) {
                int extractedDigit = Integer.parseInt(Character.toString(num.charAt(i)));
                if(extractedDigit % 2 != 0){
                    cnt++;
                    str += Integer.toString(extractedDigit);
                    if(cnt == 2)break;
                }

            }
            if(cnt == 2) System.out.println(str);
            else System.out.println("-1");

            if(tc == 0)break;
            tc--;
        }
    }
}
Fahim Hassan
  • 61
  • 1
  • 9

4 Answers4

2

Try this out hope it will work

 public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String num = scanner.nextLine();
        String str = "";

        int cnt = 0;
        for (int i = 0; i < num.length(); i++) {
            int extractedDigit = Integer.parseInt(Character.toString(num.charAt(i)));
            if (extractedDigit % 2 != 0) {
                cnt++;
                str += Integer.toString(extractedDigit);
                if (cnt == 2) break;
            }
        }
        if (cnt == 2) {
            System.out.println(str);
        } else System.out.println("-1");
    }
  • Please add some explanation to your answer. You can also read [How to Answer](https://stackoverflow.com/help/how-to-answer) –  Jan 20 '21 at 18:15
  • I got to this point, but whenever I use this same code in a while loop, it just doesn't work. – Fahim Hassan Jan 20 '21 at 18:24
2

You should learn the following things which will in turn also solve your problem:

  1. You can replace Integer.parseInt(Character.toString(num.charAt(i))) with num.charAt(i) - '0' because you can perform arithmetic operations on char in the same way you perform on int e.g. '5' - '2' gives 3.

  2. I recommend you use StringBuilder instead of String for repeated string concatenation in a loop because using String will create additional as many instances of String as the number of concatenation. Check this discussion to learn more about it. Note that you can append a char value directly to a StringBuilder.

  3. You should make a habit of enclosing the body of a block within {...} even if you have a single statement in the body. This will save you from some statement accidentally falling out of scope e.g.

    if (1 == 2)
        System.out.print("Hello");
        System.out.println("World");
    
    System.out.println("What's up?"); 
    

will print

World
What's up?

and not just

What's up?
  1. You do not need to enclose -1 with double quotes to print -1.

Incorporating all these points, you can write the solution as

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder str = new StringBuilder();
        String num = scanner.nextLine();
        int cnt = 0;
        for (int i = 0; i < num.length(); i++) {
            int extractedDigit = num.charAt(i) - '0';
            if (extractedDigit % 2 != 0) {
                cnt++;
                str.append(extractedDigit);
                if (cnt == 2) {
                    break;
                }
            }    
        }
        if (cnt == 2) {
            System.out.println(str);
        } else {
            System.out.println(-1);
        }
    }
}

A sample run:

12272
17
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
1

Your 'num' variable is always an empty string. This is because Scanner.nextInt() only reads numeric characters, and leaves trailing line separators (it reads line separators before the number though). So after you call nextInt(), the next readable character in the scanner is a line separator.

Scanner.nextLine(), as the name suggests, reads until the next line separator. This happens to be the very first character, so it returns an empty string - which contains no odd numbers.

To fix this, use Integer.parseInt(scanner.nextLine()) instead of nextInt() if the input text is on separate lines, or call scanner.nextLine() before the critical statement to read the empty line.

EDIT: Working code, assuming every input is on a separate line:

    int tc = Integer.parseInt(scanner.nextLine());
    
    while(true){
        String str="";
        int n = Integer.parseInt(scanner.nextLine());
        String num = scanner.nextLine();
        int cnt = 0;
        for (int i = 0; i < num.length(); i++) {
            int extractedDigit = Integer.parseInt(""+num.charAt(i));
            if(extractedDigit % 2 != 0){
                cnt++;
                str += Integer.toString(extractedDigit);
                if(cnt == 2)break;
            }
            
        }
        if(cnt == 2) System.out.println(str);
        else System.out.println("-1");
        if(tc == 0)break;
        tc--;
    }
  • This is somewhat confusing for me. I have used `scanner.nextInt()` to get the number of digit for the number I want to check, and `scanner.nextLine()` to read the string input. – Fahim Hassan Jan 20 '21 at 18:29
  • scanner.nextInt() doesn't read the entire line and turns it into an int, it only reads the next int and doesn't care about the rest –  Jan 20 '21 at 18:33
  • The [javadoc](https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/Scanner.html#nextInt()) says nextInt() parses the next 'token'. Tokens are separated by whitespace characters by default, and whitespace characters include space, tabulator and line separators. –  Jan 20 '21 at 18:36
1

Sorry for not suggesting the traditional approaches. This is to just give you an idea of how functional programming can make your life easier :)

    Scanner sc = new Scanner(System.in);
    String input = sc.nextLine(); // Assuming input = "123456"
    Arrays.stream(input.split("")) // returns ["1","2","3","4","5","6"]
        .map(Integer::parseInt) // returns [1,2,3,4,5,6]
        .filter(num -> num % 2 != 0) // Allows elements that pass num % 2 != 0 predicate 
        .forEach(System.out::print); //prints the elements that passed through the filter

Now, modifying for fetching the count is very easy,

 long oddElementCount = Arrays.stream(input.split("")) // returns ["1","2","3","4","5","6"]
        .map(Integer::parseInt) // returns [1,2,3,4,5,6]
        .filter(num -> num % 2 !=0) // filters all elements that do not satisfy the predicate
        .count(); //prints the count of elements that satisfy the given Predicate (num %2 != 0)
    System.out.println(oddElementCount);
Mohamed Anees A
  • 4,119
  • 1
  • 22
  • 35