ITISummer
ITISummer

Reputation: 15

problem of the class Scanner in java when Input an integer and multiline string

I met a problem when I solved an algorithm problem in java. the algorithm is as follows:

Problem description:
Given n hexadecimal positive integers, output their octal Numbers

Input format:
the first action of the input is a positive integer n (1<= n <=10) the next n lines, each line consists of a string of 0~9 uppercase,letters A~F, representing the hexadecimal positive integers to be converted, each hexadecimal number not exceeding 100,000 in length

The output format
Output n rows, each lines input corresponding octal positive integer.

【 note 】
The hexadecimal number you enter does not have a leading 0, such as 012A. The output octal number must not have a leading 0

The sample input:

2
39
123ABC

Sample output:

71
4435274

my solution is below:

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;


public class Main {
    public static void main(String[] args) throws IOException {
        String[] hexMapping = {
        "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
        "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
    };
    Map<String,String> octMapping = new HashMap<>();
    octMapping.put("000","0");
    octMapping.put("001","1");
    octMapping.put("010","2");
    octMapping.put("011","3");
    octMapping.put("100","4");
    octMapping.put("101","5");
    octMapping.put("110","6");
    octMapping.put("111","7");

    String hexString = "";
    StringBuilder hex2Bin = new StringBuilder("");
    StringBuilder bin2Oct = new StringBuilder("");

    Scanner input = new Scanner(System.in);
    int n = input.nextInt();

//  consuming the <enter> from input above
    input.nextLine();

    for (int i = 0; i < n; i++) {
        hexString = input.nextLine();
        // hex to bin
        int hexLen = hexString.length();
        for (int j = 0; j < hexLen; j++) {
            if (hexString.charAt(j)>'9') {
                hex2Bin.append(hexMapping[hexString.charAt(j)-'A'+10]);
            } else {
                hex2Bin.append(hexMapping[hexString.charAt(j)-'0']);
            }
        } //end for

        // add "00" or "0"
        int len = hex2Bin.length();
        if (len % 3 == 1) {
            hex2Bin.insert(0,"00");
        } else if (len % 3 == 2) {
            hex2Bin.insert(0,"0");
        }

        // bin to oct
        int newLen = hex2Bin.length();
        String temp = "";
        for (int j = 0; j < newLen; j+=3 ) {
            temp = octMapping.get(hex2Bin.substring(j,j+3));
            if (temp.equals("0")) {
                continue;
            }
            bin2Oct.append(temp);
        } //end for
        System.out.println(bin2Oct);
    }//end for
    input.close();
}

when I input:

1
39

or

1
123ABC

both two are correct.

but when I input:

2
39
123ABC

I can't get the correct answer.

I think the cause is the input when I use Scanner in for loop, I don't know how to solve this problem, could you tell me?

Upvotes: 1

Views: 63

Answers (2)

Bashir
Bashir

Reputation: 2051

you just have to initialize the two StringBuilder on each test case in the for loop, at the first try it will always works, because it is empty, but in the later tries you keep working with the old values and this will gives you Wrong Answer.

An other remark but it doesn't affect the final answer, if you use Scanner, you can read a String value using input.next() , this way you don't need to use nextLine which may confuse you if you use nextInt()

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;


public class Main {
    public static void main(String[] args) throws IOException {
        String[] hexMapping = {
        "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
        "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
    };
    Map<String,String> octMapping = new HashMap<>();
    octMapping.put("000","0");
    octMapping.put("001","1");
    octMapping.put("010","2");
    octMapping.put("011","3");
    octMapping.put("100","4");
    octMapping.put("101","5");
    octMapping.put("110","6");
    octMapping.put("111","7");

    String hexString = "";


    Scanner input = new Scanner(System.in);
    int n = input.nextInt();



    for (int i = 0; i < n; i++) {
        hexString = input.next();
        // hex to bin
        int hexLen = hexString.length();
        StringBuilder hex2Bin = new StringBuilder("");
        StringBuilder bin2Oct = new StringBuilder("");
        for (int j = 0; j < hexLen; j++) {
            if (hexString.charAt(j)>'9') {
                hex2Bin.append(hexMapping[hexString.charAt(j)-'A'+10]);
            } else {
                hex2Bin.append(hexMapping[hexString.charAt(j)-'0']);
            }
        } //end for

        // add "00" or "0"
        int len = hex2Bin.length();
        if (len % 3 == 1) {
            hex2Bin.insert(0,"00");
        } else if (len % 3 == 2) {
            hex2Bin.insert(0,"0");
        }

        // bin to oct
        int newLen = hex2Bin.length();
        String temp = "";
        for (int j = 0; j < newLen; j+=3 ) {
            temp = octMapping.get(hex2Bin.substring(j,j+3));
            if (temp.equals("0")) {
                continue;
            }
            bin2Oct.append(temp);
        } //end for
        System.out.println(bin2Oct);
    }//end for
    input.close();
    }
}

Upvotes: 0

cd1
cd1

Reputation: 16534

You're printing the contents of bin2Oct at the end of your loop, but that variable is reused across all iterations.

You need to declare those variables inside your loop so they are recreated each time. In other words, move the following block:

StringBuilder hex2Bin = new StringBuilder("");
StringBuilder bin2Oct = new StringBuilder("");

to your loop (after the line with for (...)).

Upvotes: 3

Related Questions