How to get number from console in java? - java

This is my method that will be called if I want to get a number from user. But if the user also enter a right number just the "else" part will run, why?
Can you explain?
public static int chooseTheTypeOfSorting() {
System.out.println("Enter 0 for merge sorting OR enter 1 for bubble sorting");
int numberFromConsole = 0;
try {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = br.readLine();
DecimalFormat df = new DecimalFormat();
Number n = df.parse(s);
numberFromConsole = n.intValue();
} catch (ParseException ex) {
Logger.getLogger(DoublyLinkedList.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(DoublyLinkedList.class.getName()).log(Level.SEVERE, null, ex);
}
return numberFromConsole;
}
and in my main method:
public static void main(String[] args) {
int i = 0;
i = getRandomNumber(10, 10000);
int p = chooseTheTypeOfSorting();
DoublyLinkedList list = new DoublyLinkedList();
for (int j = 0; j < i; j++) {
list.add(j, getRandomNumber(10, 10000));
if (p == 0) {
//do something....
}
if (p == 1) {
//do something.....
} else {
System.out.println("write the correct number ");
chooseTheTypeOfSorting();
}

The problem is you're missing an else
if (p == 0) {
//do something....
} else if (p == 1) { // you're missing the else here
//do something.....
} else {
System.out.println("write the correct number ");
chooseTheTypeOfSorting();
}
On reading number from console
Use java.util.Scanner
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
The documentation has more examples.
Note also that you can set the delimiter, and it also has many hasNextXXX methods that you can use to check against InputMismatchException.
See also
Java Tutorials - I/O - Scanning and Formatting
Design consideration
You may consider having the helper method filter out "bad" input, so that once you get the type of sorting, it's guaranteed to be valid.
You may also consider using an enum:
enum SortMode {
BUBBLE_SORT, QUICK_SORT, BOGO_SORT;
}
See also
Java Tutorials/Enum

Related

Reading certain number of elements from File in Java

I have a text file with few numbers in a line ;
10 20 30 40 50
My motto is to read 3 numbers at a time and perform some operation on it.
Please help me to learn best ways to do this job.
I need to work on numbers in this fashion,
10 20 30
20 30 40
30 40 50 .....
If my text file has a line with 100000 numbers is it suggestable to load the entire file in memory and keep traversing and performing operations or is it good to copy the entire line in an array and perform operations on it?
Here is a simple way to do it:
int a, b, c;
// try with resources, scanner will be closed when we are done.
try (Scanner scan = new Scanner(new File("input.txt"))) {
// get the first three ints.
a = scan.nextInt();
b = scan.nextInt();
c = scan.nextInt();
doSomething(a, b, c);
// while there are more
while (scan.hasNext()) {
a = b;
b = c;
c = scan.nextInt();
doSomething(a, b, c);
}
} catch (FileNotFoundException | NoSuchElementException e) {
e.printStackTrace();
}
This will read one number at a time, and perform some operation in between each read.
If you want to read all the numbers before performing operation, you can use an array list.
ArrayList<Integer> list = new ArrayList<>();
// try with, scanner will be closed when we are done.
try (Scanner scan = new Scanner(new File("input.txt"))) {
// while there are more
while (scan.hasNext()) {
list.add(scan.nextInt());
}
} catch (FileNotFoundException | NoSuchElementException e) {
e.printStackTrace();
}
Then you can iterate through them.
for (int i : list) {
}
Using an IntBuffer instead of ArrayList would work if you know how many numbers there were.
For only 100000 values it probably doesn't make much difference if you load them as you need them or load them all first. If your operation takes a long time it might be better to load them all.
Well, it depends on what you want. Load all the numbers to the memory will take more time, but operations with the numbers in memory will be faster. If you don't want to allocate a "big" portion of your memory to hold all the numbers you can read the file and at the same time do the operation. Although, it will not make much difference, since the file just hold numbers and its size won't be to big.
Below is a code sample that achieves what you want.
Full Code
public static void main (String args[]){
//Scanner will read your file
Scanner scanner = null;
try {
scanner = new Scanner(new File("file.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// tmpInts will old the tmp values that are read
int [] tmpInts = new int[3];
// Holds a controller to know if we can do the operation
int i = 0;
while(scanner.hasNextInt()){
// Do the operation only when tmpInts has 3 numbers inside it
if(i > 2){
System.out.println("Read: ["+tmpInts[0] +" "+ tmpInts[1] +" "+ tmpInts[2]+"] Sum: "+(tmpInts[0] + tmpInts[1] + tmpInts[2]));
shiftInts(tmpInts);
tmpInts[2] = scanner.nextInt(); // Read next number
} else {
tmpInts[i] = scanner.nextInt(); // Read next number
i++;
}
}
// Check if there are at least 3 numbers in the file
// If not, don't do the operation
// If yes, this is the last operation call to handle the last state of tmpInts array
if(!isEmpty(tmpInts))
System.out.println("Read: ["+tmpInts[0] +" "+ tmpInts[1] +" "+ tmpInts[2]+"] Sum: "+(tmpInts[0] + tmpInts[1] + tmpInts[2]));
scanner.close(); // IMPORTANT! Don't forget to close your scanner
}
// Shift numbers one index left to put a third one in the last index of the array after
public static void shiftInts(int[] tmpInts) {
tmpInts[0] = tmpInts[1];
tmpInts[1] = tmpInts[2];
}
// Check if array is full. If it is not it means that your file doesn't have at least 3 numbers. i choosed 0 as default value in array, you can choose another one that won't appear in your file
public static boolean isEmpty(int[] tmpInts) {
for(int i: tmpInts){
if(i == 0){
return true;
}
}
return false;
}
Hope it helped!
I took line as a String and converted into array of integers to load all numbers into the memory. We can do required operations on integer array by iteration.
Below is the sample code :
public static void main(String[] args) {
String fileName = "temp1.txt";
String line;
try {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
while ((line = bufferedReader.readLine()) != null) {
String[] inputNumbers = line.split(",");
int numbers[] = new int[inputNumbers.length];
for (int i = 0; i < inputNumbers.length; i++) {
numbers[i] = Integer.parseInt(inputNumbers[i]);
}
for (int j = 0; j < numbers.length - 2; j++) {
int sum = numbers[j] + numbers[j + 1] + numbers[j + 2];
System.out.println(sum);
}
}
bufferedReader.close();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

Print the type of object using Iterator

I write a method for printing the type of the object which not working properly. The idea is to read the input, insert them in the ArrayList and then, print their types. I would like to provide the input as follow
42
3.1415
Welcome to Hackerrank Java tutorials!
and eventually, get the output in the reverse order such as
String: Welcome to Hackerrank Java tutorials!
Double: 3.1415
Int: 42
It always come in the serial as int, double and String. The method is provided below with one solution. I'm trying to solve it with BufferedReader now.
public static void printMethod ( ){
List<Object> arr = new ArrayList<Object>();
Scanner scan = new Scanner(System.in);
int count = 0;
while (scan.hasNextLine()) {
count++;
String line = scan.nextLine();
if( count == 1 ){
try {
Integer v = Integer.valueOf(line.trim());
arr.add(v);
continue;
}
catch (NumberFormatException nfe) {
}
}
if ( count == 2 ){
try {
Double d = Double.valueOf(line.trim());
arr.add(d);
continue;
}
catch (NumberFormatException nfe) {
}
}
arr.add(line);
}
for (int i = arr.size() - 1; i >= 0; i--) {
Object obj = arr.get(i);
Class<?> type = obj.getClass();
String[] s = type.getName().toString().split("\\.") ;
if ( s[s.length - 1 ].equals("Integer") )
System.out.println( "Int" + ": " +obj.toString());
else
System.out.println(s[s.length - 1 ] + ": " +obj.toString());
// System.out.println( );
}
}
If I understand your question, then you will need to parse the supported types. Since your question lists Integer, Double and String I'll show you a way you might parse those. Also, I'd use a Scanner. Putting that together, it might look something like
List<Object> arr = new ArrayList<Object>();
Scanner scan = new Scanner(System.in);
while (scan.hasNextLine()) {
String line = scan.nextLine();
try {
Integer v = Integer.valueOf(line.trim());
arr.add(v);
continue;
} catch (NumberFormatException nfe) {
}
try {
Double d = Double.valueOf(line.trim());
arr.add(d);
continue;
} catch (NumberFormatException nfe) {
}
arr.add(line);
}
for (int i = arr.size() - 1; i >= 0; i--) {
Object obj = arr.get(i);
Class<?> type = obj.getClass();
System.out.printf("%s: %s%n", type.getName(), obj.toString());
}
Which I ran (and received your expected output) lke
42
3.1415
Welcome to Hackerrank Java tutorials!
java.lang.String: Welcome to Hackerrank Java tutorials!
java.lang.Double: 3.1415
java.lang.Integer: 42

Can i make following code any Faster

I would like to make the following code faster, without changing the reading/writing from standard console. The first line contains the number of inputs and the subsequent lines contain a set of Integers.
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws java.lang.Exception {
try {
java.io.BufferedReader r = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
int a = Integer.parseInt(r.readLine());
for (int i = 0; i < a; i++) {
StringTokenizer st = new StringTokenizer(r.readLine());
while (st.hasMoreTokens()) {
int first = Integer.parseInt(st.nextToken());
int second = Integer.parseInt(st.nextToken());
if (first < second)
System.out.println("<");
else if (first > second)
System.out.println(">");
else
System.out.println("=");
}
}
} catch (Exception e) {
System.err.print(e.getMessage());
}
}
}
You are performing a lot of redundant autoboxing and outboxing there which could be saved if you define first and second as primitive ints instead of java.lang.Integer wrapper classes. I doubt, however, that for any reasonable size of input you'd even notice the difference.
Here are a few suggestions, I am not sure these will help a lot.
1) This,
if (first < second)
System.out.println("<");
else if (first > second)
System.out.println(">");
else
System.out.println("=");
can be changed to
System.out.println(first < second
? "<"
: first > second
? ">"
: "="
);
2) Since you are using a throws clause and your try-catch does nothing you can remove it.
3) Here,
int first = Integer.parseInt(st.nextToken());
int second = Integer.parseInt(st.nextToken());
You are not checking for hasMoreTokens() the second time.
4) Use split() instead of StringTokenizer. More on that here and here.
You may consider to use the BufferedReader's constructor below:
public BufferedReader(Reader in, int sz)
Giving the sz parameter a reasonable high value, can avoid the buffer to be refilled too often.
As a side note, while readLine() retuns null if the end of the stream has been reached, it's better to check its return value before calling new StringTokenizer(r.readLine()) and Integer.parseInt(r.readLine()).
The edited class follows:
public class Main {
public static void main(String[] args) {
BufferedReader r;
String line;
StringTokenizer st;
int a, first, second;
r = new BufferedReader(new InputStreamReader(System.in), 4096);
try {
line = r.readLine();
if (line != null) {
a = Integer.parseInt(line);
for (int i = 0; i < a; ++i) {
line = r.readLine();
if (line == null)
break;
st = new StringTokenizer(line);
while (st.hasMoreTokens()) {
first = Integer.parseInt(st.nextToken());
second = Integer.parseInt(st.nextToken());
if (first < second)
System.out.println("<");
else if (first > second)
System.out.println(">");
else
System.out.println("=");
}
}
}
r.close();
} catch (Exception e) {
System.err.print(e.getMessage());
}
}
}

UVa 11616 Roman Numerals Time Limit Exceeded - I am receiving Time Limit Exceeded consistently

I am working on a problem on UVa for general programming practice, as I want to get better at programming competitively. However I am having trouble with this problem - Roman Numerals. In this problem the goal is to take input which will be in the form of either a Roman numeral or Arabic numeral and then I must convert from one to the other. I feel that my code should not have trouble in processing fast enough yet according to the online judge, it does not process fast enough. I need to help finding out how I may optimize my code so that it will run faster and not receive TLE.
Below is my program, any help as to explaining why I am receiving Time Limit Exceeded would be greatly appreciated. Thanks in advance.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Main {
private static String order = "IVXLCDM";
private static String order2 = "IXCM"; // These chars are the result of 10^n (n depending on index in the string)
private static String order3 = "VLD"; // These chars are products of 5*10^n (n depending on index in the string)
public static void main(String[] args) {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String ans = "";
while (true) {
String read = "";
int aNum = 0;
String rNum = "";
try {
read = br.readLine();
if (read=="")
break;
} catch (IOException e) {
if (read=="")
break;
e.printStackTrace();
}
try {
aNum = Integer.parseInt(read);
// System.out.println(aNum);
int thousands = aNum/1000;
// System.out.println(thousands);
int hundreds = aNum/100;
hundreds = hundreds%10;
// System.out.println(hundreds);
int tens = aNum%100;
tens = tens/10;
// System.out.println(tens);
int ones = aNum%10;
// System.out.println(ones);
rNum+= a2R(thousands,"M");
rNum+= a2R(hundreds,"C");
rNum+= a2R(tens,"X");
rNum+= a2R(ones,"I");
// System.out.println(rNum);
ans+=(rNum+"\n");
// System.out.print(ans);
} catch (NumberFormatException c) {
rNum = read;
if (rNum.equals(""))
break;
aNum = r2A(rNum);
// System.out.println(aNum);
ans+=(aNum+"\n");
// System.out.print(ans);
}
}
System.out.print(ans);
}
private static int r2A(String rNum) {
int aNum = 0;
for (int i = order.length()-1; i >= 0; i--) {
char curChar = order.charAt(i);
while (rNum.indexOf(curChar)!=-1) {
if (rNum.indexOf(curChar)==0) {
if (order2.indexOf(curChar)!=-1) {
aNum+=((int)Math.pow(10, order2.indexOf(curChar)));
}
else if (order3.indexOf(curChar)!=-1) {
aNum+=(5*((int)Math.pow(10, order3.indexOf(curChar))));
}
rNum = rNum.substring(1);
}
else if (rNum.indexOf(curChar)==1) {
if (order2.indexOf(curChar)!=-1) {
aNum+=((int)(Math.pow(10, order2.indexOf(curChar))-Math.pow(10, order2.indexOf(curChar)-1)));
}
else if (order3.indexOf(curChar)!=-1) {
aNum+=((int)((5*Math.pow(10, order3.indexOf(curChar)))-Math.pow(10,order3.indexOf(curChar))));
}
rNum = rNum.substring(2);
}
}
}
return aNum;
}
private static String a2R(int num, String theNum) {
// num is the digit of an Arabic digit number to be replaced by Roman Numerals for that digit
// theNum is the value of Roman Numerals that would go into the specific digit place (tens, ones,...)
String rNum = "";
if (!theNum.equals("M")) {
if (num==9) {
rNum = theNum + order.charAt(order.indexOf(theNum)+2);
}
else if (num==4) {
rNum = theNum + order.charAt(order.indexOf(theNum)+1);
}
else if (num>=5) {
rNum+= order.charAt(order.indexOf(theNum)+1);
for (int i = 0; i < num-5; i++) {
rNum+=theNum;
}
}
else {
for (int i = 0; i < num; i++) {
rNum+=theNum;
}
}
}
else {
for (int i = 0; i < num; i++) {
rNum+=theNum;
}
}
return rNum;
}
}
`
I expect the TLE is being caused by your program never terminating.
Currently you have a while (true) loop, which breaks when you see a blank line.
According to the problem however...
The input consists of several lines, each one containing
either an Arabic or a Roman number n, where 0 < n < 4000.
Nowhere does it state that there will be an extra blank line terminating the input.
So your program will not terminate, forever waiting until an extra blank line has been entered.
Instead of reading your input like this
while (true) {
String read = "";
int aNum = 0;
String rNum = "";
try {
read = br.readLine();
if (read=="")
break;
} catch (IOException e) {
if (read=="")
break;
e.printStackTrace();
}
//etc
try this instead
String read = "";
while ((read = br.readLine()) != null) {
int aNum = 0;
String rNum = "";
//etc
I solved my problem by going about it in a different manner, I used a couple of HashMaps to map Roman numeral values to Arabic numeral values and vice versa. I had four helper methods: one would set up the hashmaps, another would convert from Roman numeral to Arabic numeral, and the other two would work together to convert from Arabic numeral to Roman numeral.
The method that converted from Roman to Arabic would go through the string in a for loop starting from the beginning of the string. It would check if the length of the string was greater than one, and if so it would then check if the substring of the first two values are in the Roman to Arabic hashmap. If so, it would then add the value that the Roman numeral value equates to to an int variable. The method would also check substrings of length 1.
In the methods that converted from Arabic to Roman, the input integer would first be analyzed then it would be torn apart into its little pieces. In the first method, four integer values would first be produced: the thousands value, the hundreds value, the tens value, then the ones value. The second method would organize these values into the correct Roman numeral form.
Thanks to everybody who helped me solve this problem, I did not realize some of the mistakes that I made, probably due to my inexperience in programming so this was a great learning experience for myself.
Below is my solution:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
class Main {
private static HashMap<String,Integer> r2A = new HashMap<String,Integer>();
private static HashMap<Integer,String> a2R = new HashMap<Integer,String>();
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
makeMaps();
String read;
StringBuilder answers = new StringBuilder("");
while ((read=br.readLine())!=null) {
int aNum = 0;
String rNum = "";
try {
aNum = Integer.parseInt(read);
System.out.println(arab2Roman(aNum));
} catch (NumberFormatException c) {
rNum = read;
int ans = roman2Arab(rNum);
System.out.println(ans);
}
}
}
private static int roman2Arab(String rNum) {
int aNum = 0;
for (int i = 0; i < rNum.length(); i++) {
boolean done = false;
String theNum = rNum.substring(i,i+1);
if (i < rNum.length()-1) {
String part = rNum.substring(i, i+2);
if (r2A.containsKey(part)) {
aNum+=r2A.get(part);
i++;
done = true;
}
}
if (!done) {
if (r2A.containsKey(theNum)) {
aNum+=r2A.get(theNum);
}
}
}
return aNum;
}
private static String arab2Roman(int num) {
StringBuilder rNum = new StringBuilder("");
int thousands = num-(num%1000);
int hundreds = ((num/100)%10)*100;
int tens = ((num/10)%10)*10;
int ones = num%10;
rNum.append(simpleConv(thousands,"thousands"));
rNum.append(simpleConv(hundreds,"hundreds"));
rNum.append(simpleConv(tens,"tens"));
rNum.append(simpleConv(ones,"ones"));
return rNum.toString();
}
private static String simpleConv(int num, String place) {
StringBuilder ans = new StringBuilder("");
int pNum = (place.equals("thousands")) ? 1000 : (place.equals("hundreds")) ? 100 : (place.equals("tens")) ? 10 : 1;
if (a2R.containsKey(num)) {
ans.append(a2R.get(num));
}
else {
if (num/pNum>=5) {
ans.append(a2R.get(5*pNum));
for (int i = 0; i < ((num/pNum)-5); i++) {
ans.append(a2R.get(pNum));
}
}
else {
for (int i = 0; i < num/pNum; i++) {
ans.append(a2R.get(pNum));
}
}
}
return ans.toString();
}
private static void makeMaps() {
// First r2A
r2A.put("I", 1);
r2A.put("IV", 4);
r2A.put("V", 5);
r2A.put("IX", 9);
r2A.put("X", 10);
r2A.put("XL", 40);
r2A.put("L", 50);
r2A.put("XC", 90);
r2A.put("C", 100);
r2A.put("CD", 400);
r2A.put("D", 500);
r2A.put("CM", 900);
r2A.put("M", 1000);
// Second a2R
a2R.put(1, "I");
a2R.put(4, "IV");
a2R.put(5, "V");
a2R.put(9, "IX");
a2R.put(10, "X");
a2R.put(40, "XL");
a2R.put(50, "L");
a2R.put(90, "XC");
a2R.put(100, "C");
a2R.put(400, "CD");
a2R.put(500, "D");
a2R.put(900, "CM");
a2R.put(1000, "M");
}
}

Using the same values in separate if statements in java

I am working on a problem where I have a menu option 1. to shuffle the word, 2 to take the shuffle word and try to fix it by changing the array index numbers.
I did this part if (input==1) shuffle the word.
I now have to take that the same shuffle word in in if (input==2) section and try to fix it. Can anybody guide me how can I use the same values in this block if(input==1)?
import java.util.Scanner;
import java.io.*;
import java.util.*;
public class Project2 {
public static void main(String[] args) {
while (true) {
System.out.println("Select an item from below: \n");
System.out.println("(1) Mix");
System.out.println("(2) Solve");
System.out.println("(3) Quit");
int input;
Scanner scan = new Scanner(System.in);
input = scan.nextInt();
String team;
String mix_word;
char orig_team[];
char mix_team[];
boolean Result;
// System.out.println(input);
if (input == 1) {
team = orig();
System.out.println(team);
mix_word = mix(team);
System.out.println(mix_word);
orig_team = team.toCharArray();
mix_team = mix_word.toCharArray();
int arg_length = mix_team.length;
}
if (input == 2) {
}
if (input == 3) {
break;
}
if (input > 3 || input <= 0) {
System.out.println("input accurate numbers 1 or 2 or 3");
}
}
}
static String mix(String Team) {
String word = shuffle(Team);
return word;
}
static String shuffle(String input) {
List<Character> characters = new ArrayList<Character>();
for (char c : input.toCharArray()) {
characters.add(c);
}
StringBuilder output = new StringBuilder(input.length());
while (characters.size() != 0) {
int randPicker = (int) (Math.random() * characters.size());
output.append(characters.remove(randPicker));
}
return output.toString();
}
static String orig()
{
String[] lines = new String[1000];// Enough lines.
int counter = 0;
try {
File file = new File("input.txt");// The path of the File
FileReader fileReader1 = new FileReader(file);
BufferedReader buffer = new BufferedReader(fileReader1);
boolean flag = true;
while (true) {
try {
lines[counter] = buffer.readLine();// Store a line in the
// array.
if (lines[counter] == null) {// If there isn't any more
// lines.
buffer.close();
fileReader1.close();
break;// Stop reading and close the readers.
}
counter++;
} catch (Exception ex) {
break;
}
}
} catch (FileNotFoundException ex) {
System.out.println("File not found.");
} catch (IOException ex) {
System.out.println("Exception ocurred.");
}
int pick;
Random rand = new Random();
pick = rand.nextInt(counter) + 0;
return (lines[pick]);
}
}
In every loop cycle (which handles a single user input) you declare your variables, so their scope (the access range) is limited to that cycle.
If you declare your variables outside the while-loop, their scope will stretch over the whole loop (until the end of the method):
public static void main(String[] args) {
String team = "";
String mix_word = "";
char orig_team[] = null;
char mix_team[] = null;
boolean Result = false;
while (true) {
// ** your usual input handling here **
}
}
Also be sure to initialize them (e.g. with a default value), or else the program will not compile.
Another way would be to create member- or class-variables, which would have the advantage of automatic initialization and a larger scope.
This is a rather pathological use case of the switch statement but you can take advantage of the drop-through and do the following:
switch(input) {
case 1:
team = orig();
System.out.println(team);
mix_word = mix(team);
System.out.println(mix_word);
orig_team = team.toCharArray();
mix_team = mix_word.toCharArray();
arg_length = mix_team.length;
// No break; here!
case 2:
// do the rest of your thing as if it were case 2
break;
case 3:
break;
default:
System.out.println("input accurate numbers 1 or 2 or 3");
}

Categories