Input from the console in java - java

I know this is a basic question but I have been trying hard to find Which method I can use if I have to take 2 {123,456} as the input from console where 2 is the number of inputs to the array and {123,456} are inputs to the array. Should I be using Regex for this since it has { symbols or can it be done by scanner alone??

You can read the array part as String and then strip the curly braces using substring. Convert the String to int and store into an array.
import java.util.Scanner;
public class ReadArray {
public static void main(String[] args) {
Scanner read = new Scanner(System.in);
int count = read.nextInt();
String arrayLine = read.next();
int array[] = new int[count];
String elements[] = arrayLine.split(",");
elements[0] = elements[0].substring(1);
elements[count-1] = elements[count-1].substring(0, elements[count-1].length()-1);
for (int i=0; i<count; i++) {
array[i] = Integer.parseInt(elements[i]);
}
for (int i : array) {
System.out.println(i);
}
}
}
Input :
2 {123,456}
Output :
123
456

Assuming you have read the input as a string, you can do the following:
String[] inputs = input.split(" ");
int arrayLength = Integer.parseInt(inputs[0]);
String inputStringData = inputs[1].substring(1, inputs[1].length());
String[] arrayElements = inputStringData.split(",");
int[] array = new int[arrayLength];
for(int i=0; i<array.length; i++) {
array[i] = Integer.parseInt(arrayElements[i]);
}

Related

Java Stdin Cannot convert from String[] to String, but inputs are String?

I am doing a programming assignment that takes all of its input from stdin. The first input is an int n to tell you how many strings will follow, and the next n inputs are strings of varying lengths. The goal is to find the longest string(s) and print them.
I thought this was easy, but for the life of me, I cannot get the stdin to work with me. The eclipse arguments entered are (separated by enter):
3
a2
b3c
7
Yet I run the program, and it tells me it cannot convert from String[] to String. I do not understand how any of the above are String[]. The code is below:
import java.util.Scanner;
public class A2P1 {
public static void main(String[] args) {
int size = Integer.parseInt(args[0]);
String[] str = new String[size];
Scanner sc = new Scanner(System.in);
for (int i=0; i < size; i++) {
str[i] = sc.nextLine().split(" "); // The error
//str[i] = sc.next(); This line and the line below throw
//str[i] = sc.nextLine(); no errors, but also gives no output.
}
String[] longest = new String[size];
String[] temp = new String[size];
longest[0] = str[0];
int numToBeat = str[0].length();
int k = 0;
for (int i=0; i < size; i++) {
if (str[i].length() > numToBeat) {
numToBeat = str[i].length();
k = 0;
longest = temp;
longest[k] = str[i];
k++;
}
else if (str[i].length() == numToBeat) {
longest[k] = str[i];
}
}
System.out.println("The longest input strings are:");
for (int i=0; i < k; i++) {
System.out.println(longest[i]);
}
sc.close();
}
}
Tried:
Changing str[i] = sc.nextLine().split(" "); to its other variations in the code
Changing input values
Googling stdin for the last hour trying to find any documentation that helps me
If you are using eclipse arguments separated by enter then your logic is wrong:
according to your logic get 1st element from the eclipse argument like args[0]
another Input is taken from the console.
if you need to take all elements from the eclipse argument follow the below code:
public class A2P1 {
public static void main(String[] args) {
int size = Integer.parseInt(args[0]);
String[] str = new String[size];
int length=0;
String loggestString="";
for (int i=1; i < size; i++) {
str[i] = args[i];
int strLen = str[i].length();
if(strLen>length) {
length=strLen;
loggestString=str[i];
}
}
System.out.println(loggestString);
}
}

Java: Most Efficient Way to Get Input Integer Array

I'm working on a problem that requires me to store a very large amount of integers into an integer array. The input is formatted so that one line displays the amount of integers and the next displays all of the values meant to be stored. Ex:
3
12 45 67
In the problem there is closer to 100,000 integers to be stored. Currently I am using this method of storing the integers:
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] iVau = new int[n];
String[] temp = scanner.nextLine().split(" ");
for(int i = 0; i < n; i++) {
iVau[i] = Integer.parseInt(temp[i]);
}
This works fine, however the problem I am solving has a strict time limit and my current solution is exceeding it. I know that there is a more efficient way to store this input using buffered readers and input streams, but I don't know how to do it, can someone please show me.
The way you are using Scanner makes your program save a String containing the whole numbers at once, in memory. With 100000 numbers in the 2nd line of your input, it is not so efficient, you could read numbers one after the other without keeping the previous one in memory. So, this way, avoiding using Scanner.readLine() should make your program run faster. You will not have to read the whole line one time, and read a 2nd time this String to parse the integers from it: you will do both of these operations only once.
Here is an example. The method testing() does not use any Scanner. The method testing2() is the one you provided. The file tst.txt contains 100000 numbers. The output from this program, on my Mac Mini (Intel Core i5#2.6GHz) is:
duration without reading one line at a time, without using a Scanner instance: 140 ms
duration when reading one line at a time with a Scanner instance: 198 ms
As you can see, not using Scanner makes your program 41% faster (integer part of (198-140)/140*100 equals 41).
package test1;
import java.io.*;
import java.util.*;
public class Test {
// Read and parse an Int from the stream: 2 operations at once
private static int readInt(InputStreamReader ir) throws IOException {
StringBuffer str = new StringBuffer();
int c;
do { c = ir.read(); } while (c < '0' || c > '9');
do {
str.append(Character.toString((char) c));
c = ir.read();
} while (!(c < '0' || c > '9'));
return Integer.parseInt(str.toString());
}
// Parsing the input step by step
private static void testing(File f) throws IOException {
InputStreamReader ir = new InputStreamReader(new BufferedInputStream(new FileInputStream(f)));
int n = readInt(ir);
int [] iVau = new int[n];
for (int i = 0; i < n; i++) iVau[i] = readInt(ir);
ir.close();
}
// Your code
private static void testing2(File f) throws IOException {
Scanner scanner = new Scanner(f);
int n = scanner.nextInt();
int[] iVau = new int[n];
scanner.nextLine();
String[] temp = scanner.nextLine().split(" ");
for(int i = 0; i < n; i++)
iVau[i] = Integer.parseInt(temp[i]);
scanner.close();
}
// Compare durations
public static void main(String[] args) throws IOException {
File f = new File("/tmp/tst.txt");
// My proposal
long t = System.currentTimeMillis();
testing(f);
System.out.println("duration without reading one line at a time, without using a Scanner instance: " + (System.currentTimeMillis() - t) + " ms");
// Your code
t = System.currentTimeMillis();
testing2(f);
System.out.println("duration when reading one line at a time with a Scanner instance: " + (System.currentTimeMillis() - t) + " ms");
}
}
NOTE: creating the input file is done this way, with bash or zsh:
echo 100000 > /tmp/tst.txt
for i in {1..100000}
do
echo -n $i" " >> /tmp/tst.txt
done
I believe this is what you're looking for. A BufferedReader can only read a line at a time, so it is necessary to split the line and cast Strings to ints.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
String[] line = br.readLine().split(" ");
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(line[i]);
}
} catch (IOException e) {
e.getStackTrace();
}
Just a thought, String.split returns an array of Strings. You say the input can be around 100,000 values. So in order to split the array in this way, String.split must be iterating through each element. Now in parsing the new array of strings to Integers you have iterated through the collection twice. You could do this in one iteration with a few small tweaks.
Scanner scanner = new Scanner(System.in);
String tmp = scanner.nextLine();
scanner = new Scanner(tmp);
for(int i = 0; scanner.hasNextInt(); i++) {
arr[i] = scanner.nextInt();
}
The reason for linking the scanner to a String instead of leaving it on System.in is so that it ends properly. It doesn't open System.in for user input on the last token. I believe in big O notation this is the difference between O(n) and O(2n) where the original snippet is O(2n)
I am not quite sure why OP has to use Integer.parseInt(s) here since Scanner can just do the parsing directly by new Scanner(File source).
Here is a demo/test for this idea:
public class NextInt {
public static void main(String... args) {
prepareInputFile(1000, 500); // create 1_000 arrays which each contains 500 numbers;
Timer.timer(() -> readFromFile(), 20, "NextInt"); // read from the file 20 times using Scanner.nextInt();
Timer.timer(() -> readTest(), 20, "Split"); // read from the file 20 times using split() and Integer.parseInt();
}
private static void readTest() {
Path inputPath = Paths.get(Paths.get("").toAbsolutePath().toString().concat("/src/main/java/io/input.txt"));
try (Scanner scanner = new Scanner(new File(inputPath.toString()))) {
int n = Integer.valueOf(scanner.nextLine());
int[] iVau = new int[n];
String[] temp = scanner.nextLine().split(" ");
for (int i = 0; i < n; i++) {
iVau[i] = Integer.parseInt(temp[i]);
}
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
private static void readFromFile() {
Path inputPath = Paths.get(Paths.get("").toAbsolutePath().toString().concat("/src/main/java/io/input.txt"));
try (Scanner scanner = new Scanner(new File(inputPath.toString()))) {
while (scanner.hasNextInt()) {
int arrSize = scanner.nextInt();
int[] arr = new int[arrSize];
for (int i = 0; i < arrSize; ++i) {
arr[i] = scanner.nextInt();
}
// System.out.println(Arrays.toString(arr));
}
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
private static void prepareInputFile(int arrCount, int arrSize) {
Path outputPath = Paths.get(Paths.get("").toAbsolutePath().toString().concat("/src/main/java/io/input.txt"));
List<String> lines = new ArrayList<>();
for (int i = 0; i < arrCount; ++i) {
int[] arr = new int[arrSize];
for (int j = 0; j < arrSize; ++j) {
arr[j] = new Random().nextInt();
}
lines.add(String.valueOf(arrSize));
lines.add(Arrays.stream(arr).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
}
try {
Files.write(outputPath, lines);
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
}
Locally tested it with 1_000 arrays while each array has 500 numbers, reading all the elements cost about: 340ms using Scanner.nextInt() while OP's method about 1.5ms.
NextInt: LongSummaryStatistics{count=20, sum=6793762162, min=315793916, average=339688108.100000, max=618922475}
Split: LongSummaryStatistics{count=20, sum=26073528, min=740860, average=1303676.400000, max=5724370}
So I really have doubt the issue lies in the input reading.
Since in your case you are aware of the total count of elements all that you have to do is to read X integers from the second line. Here is an example:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int count = in.nextInt();
int array[] = new int[count];
for (int i = 0; i < count; i++) {
array[i] = in.nextInt();
}
}
If this is not fast enough, which I doubt, then you could switch to the use of a BufferedReader as follows:
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int count = Integer.parseInt(in.readLine());
int array[] = new int[count];
for (int i = 0; i < count; i++) {
int nextInteger = 0;
int nextChar = in.read();
do {
nextInteger = nextInteger * 10 + (nextChar - '0');
nextChar = in.read();
} while (nextChar != -1 && nextChar != (int)' ');
array[i] = nextInteger;
}
}
In your case the input will be aways valid so this means that each of the integers will be separated by a single whitespace and the input will end up with EoF character.
If both are still slow enough for you then you could keep looking for more articles about Reading Integers in Java, Competative programming like this one: https://www.geeksforgeeks.org/fast-io-in-java-in-competitive-programming/
Still my favorite language when it comes to competitions will always be C :) Good luck and enjoy!

Java: Possible to use a single for-loop instead of two?

My code is as below. It first takes input from user and prints it in reverse. I'm new to Java. I achieve this by using two 'for loops' to first iterate through the input and another for-loop to print the numbers in reverse. My question is if there's any way to improve my code - by using just a single loop perhaps? Any suggestion is appreciated. Thank you.
public static void main (String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int arr[] = new int[n];
for (int arr_i = 0; arr_i < n; arr_i++) {
arr[arr_i] = in.nextInt();
}
for (int reverse_i = n-1; reverse_i >= 0; reverse_i--) {
System.out.print(arr[reverse_i]);
if (reverse_i != 0) {
System.out.print(" ");
}
}
}
An example input:
4
1 2 3 4
Expected output:
4 3 2 1
Use a StringBuilder and always insert at 0 index.
See: Oracle » JavaDocs » 1.7 » java.lang.StringBuilder.insert(int, int)
StringBuilder bld = new StringBuilder();
for (int arr_i = 0; arr_i < n; arr_i++) {
int i = in.nextInt();
bld.insert(0, i);
}
System.out.println(bld.toString());
The simplest approach I found is to use String Builder here:
Scanner in = new Scanner(System.in);
StringBuilder stringBuilder = new StringBuilder();
while (in.hasNext()) {
stringBuilder.append(in.next());
if(in.hasNext()) {
stringBuilder.append(" ");
}
}
System.out.print(stringBuilder.reverse());
First, you might reverse your elements as you insert them in the array. Then, assuming you are using Java 8+, you could use an IntStream instead of a loop and print with a basic Collector. Like,
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] arr = new int[n];
IntStream.range(0, n).forEachOrdered(i -> arr[n - i - 1] = in.nextInt());
System.out.println(IntStream.of(arr).mapToObj(String::valueOf)
.collect(Collectors.joining(" ")));
I am not sure about the requirements of your request, but you do not necessarily have to use an array for this. You can concatenate the inputs into a String in reverse order like so.
public static void main(String[] args) {
System in = new Scanner(System.in);
int n = in.nextInt();
String allNumbers = "";
for (int i = 0; i < n; i++) {
int current = in.nextInt();
allNumbers = current + " " + allNumbers;
}
if(allNumbers != ""){
allNumbers = allNumbers.substring(0,allNumbers.length()-1);
}
System.out.println(allNumbers);
}
Java has inbuilt String method for the same. If your input is a String, you can use the below-
String s1 = new String("new");
String s2 = s1.reverse();
System.out.println(s2) // wen

How to convert a string array to an int array?

How do I convert a string like:
"114 214 219"
Into an an int array so I have something like this stored in my int array:
int[] couseNumbers = int[3];
for(int i = 0; i < 3; i++){
courseNumbers[i] = Integer.parseInt(/*get int in the string array*/);
}
Split the String into an array first.
String[] stringArray = "114 214 219".split(" ");
Then in the loop you can access that array:
courseNumbers[i] = Integer.parseInt(stringArray[i])
Try this
String s = "1 2 3";
String array[] = s.split(" "); //Splits the Array by spaces
int a[] = new int[array.length]; //Makes new int array
for(int i=0;i<a.length;i++){
a[i] = Integer.parseInt(array[i]); //Converts String to int
}
Using Java 8 streams.
List<Integer> courseNumbers = Arrays.stream("1123 213 23"
.split(" ")).map(x-> Integer.parseInt(x))
.collect(Collectors.toList());
Answer above by Eduardo Dennis will not work as string cannot convert to int directly. You can do something like this.
public static void main(String []args){
String s = "114 214 219";
String [] courseNumbers = s.split(" ");
Integer [] intArray = new Integer[courseNumbers.length];
for(int i= 0; i < courseNumbers.length; i++){
intArray[i] = Integer.parseInt(courseNumbers[i]);
}
}

How can i print my array using Arrays.toString(reverse) without[]

how can i print the result without brackets
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] arr = new int[n];
for(int i=0; i < n; i++){
arr[i] = in.nextInt();
}
int[] reverse =new int[n];
for (int i = 0; i < reverse.length; i++) {
reverse[i]=arr[arr.length-1-i];
}
in.close();
}
}
In java8, you can conveniently do any kind of String output using join, there you will have to do some manual reversing though:
String output = String.join(", ", arr);
You can't change the implementation of Arrays.toString() so you can't print your array like that.
Although, you can assign it to an string variable and then manipulate that string as you desire.
String str = Arrays.toString(reverse);
str = str.substring(1, str.length() - 1);

Categories