Multiple integer read in java with bufferedreader in java - java

I working on a program where I have to read about 10^6 integers.
I tried working with the scanner class however when i tried for 800000*3 inputs, it took around 12.38 seconds.
I also tried tried to work with the BufferedReader which actually worked faster but then it does not take the input i give as desired.
For e.g. if I want to read 3 numbers separated with a space, three consecutive nextInt() would work, but such is not the case for BufferedReader, it accepts the space as a string and while parsing the string into integer throws NumberFormatException exception.
input e.g. "8347 394730 3487", all three numbers must be stored separately.
code e.g
public static void main(String[] args) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String b=br.readLine();
int x=Integer.parseInt(b);
b=br.readLine();
int x1=Integer.parseInt(b);
b=br.readLine();
int x2=Integer.parseInt(b);
System.out.println(x+x1+x2);
}
Also the numbers can be as large as 10^10.
So I need help in using BufferedReader for such input. Also if at all there is any other alternate but faster method for reading integers, will be good enough.
Thank you

get the String and then use this :
String[] numberList = yourString.split("\\s+");
List<Integer> myList = new ArrayList<Integer>();
for(String num : numberList){
myList.add(Integer.parseInt(num));
}
update* : please try this one
public class Answer {
public static void main(String[] args) throws Exception {
List<String> eachLineList = new ArrayList<String>();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String b = br.readLine();
eachLineList.add(b.trim()); //Line 1 added to String list
b = br.readLine();
eachLineList.add(b.trim()); //Line 2 added to String list
b = br.readLine();
eachLineList.add(b.trim()); //List 3 added to String list
String[] numbers;
for (String line : eachLineList) {
numbers = line.split("\\s+");
if (numbers.length <= 1) {
//means if there was one or less integer each line don't do anything
break;
} else {
int intNum;
int temp = 0;
for (String num : numbers) {
intNum = Integer.parseInt(num);
temp += intNum;
}
System.out.println(temp);
}
}
}}
if you enter something like this "8347 394730 3487" in each line the sum will be return back to you ~

You may want to try receiving it as a String.
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String b=br.readLine();
String[] token = b.split(" "); //Split into String array by space
int[] num = new int[token.length]; //Create int array
for(int x=0; x<token.length; x++)
num[x] = Integer.parseInt(token[x]); //Store all string array into int array
for(int x=0; x<num.length; x++) //Printing
System.out.print(num[x] + " ");
Given your input in one line with spaces, the output is as follows:
Output:8347 394730 3487

YOu can check below code once.
public static void main(String[] args) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String []b=br.readLine().split(" ");
for(int i=0;i<b.length;i++)
{
System.out.print(Integer.parseInt(b[i]));
}
}

I managed to get the answer somehow, with a little help from stackoverflow ofcourse
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String b=br.readLine();
String[] numbers=b.split(" ");
long[] x=new long[numbers.length];
for(int i=0;i<numbers.length;i++)
{
x[i]=Long.parseLong(numbers[i]);
System.out.println(x[i]);
}

The String.split(separator) method can be used to split a string into an array of strings, with the separator regex providing the separator. Refer to the String and Pattern javadoc for the complete description.
However, if you are really concerned about performance, you could potentially reduce the time even further by using String.indexOf and String.substring to extract the numbers for parsing. Or potentially parse them yourself to avoid the overhead of creating strings.

Related

Java - Adding a new line every n characters without breaking apart the word

So I have been trying to get a user inputted string to have a newline every n amount of characters. What I have found is a basically what I have written, I am pretty new to Java(Python has a function to .fill but I cant figure this out in Java) and cant seem to get my string to not break words apart. I set the program to "\n" every 10 characters but then it breaks some words right in the middle... I want it to take that word and move it to the next line if it will not fit into the 10 character limit.
import java.util.Scanner;
public class Wrap {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter your text: ");
String newString = scan.nextLine();
newString = newString.replaceAll(".{10}", "$0\n");
System.out.println(newString);
/** Second Method, still cuts the words off...
StringBuilder builtString = new StringBuilder();
int i = 0;
while ((i= builtString.indexOf(newString, i + 10)) != -1) {
builtString.replace(i, i+1, "\n");
}
System.out.println(builtString);
*/
System.out.println(newString);
}
}
Words are broken apart :(
Output:
This is a
test and i
t doesnt s
eem to be
working pr
operly.
In Python I got this output which was what I wanted, but Java doesn't seem to have a textwrap function that's "easy" like Python's or at least I haven't figured it out yet.
Desired Output
public static void main(String[] args) {
String text = "This is a test and it doesnt seem to be working properly.";
String[] works = text.split(" "); // get list of works
StringBuilder line = new StringBuilder();
StringBuilder result = new StringBuilder();
for (String work : works) {
if (line.length() + work.length() > 10) { //add line to result if it full
result.append(line).append("\n");
line = new StringBuilder(); //reset line is empty
}
line.append(work).append(" ");
}
result.append(line);
System.out.println(result.toString());
}

I read my text file, now how do I store the values into a 2D array?

As mentioned, I already managed to read in the file, I'm looking for a method to added to a 2D array. This is what I read:
20 10 8
4.5 8.45 12.2
8.0 2.5 4.0
1.0 15.0 18.0
3.5 3.5 3.5
6.0 5.0 10.0
import java.io.*;
import java.util.*;
public class Packages
{
public static void main(String[] args)throws IOException,FileNotFoundException
{
BufferedReader reader = new BufferedReader(new FileReader("Dimensions.txt"));
while (true)
{
String line = reader.readLine();
if(line==null);
{
break;
}
System.out.println(line);
}
reader.close();
}
}
The following solution uses a 2D array to store the numbers from your file. This would be an appropriate solution if the structure of your input is both known and well-defined. By this I mean that every row has three numbers, and you also know how many rows there are. If not, then you might want to use a Java collection class instead here.
public static void main(String[] args) throws IOException, FileNotFoundException {
// change this value to whatever row count you actually have
int NUM_ROWS = 100;
double[][] array = new double[NUM_ROWS][3];
BufferedReader reader = new BufferedReader(new FileReader("Dimensions.txt"));
int counter = 0;
while (true) {
String line = reader.readLine();
if (line == null) break;
String[] parts = line.trim().split("\\s+");
for (int i=0; i < 3; ++i) {
array[counter][i] = Double.parseDouble(parts[i]);
}
System.out.println(line);
++counter;
}
reader.close();
}
Create a scanner to read the line, Scanner scanner = new Scanner(line).
Create a loop that reads next item, scanner.next() or scanner.nextDouble() while it has next.
Put each into array at its given spot by maintaining a count for lineNumber and doubleCount. If you do not know the dimension size you will have to do a loop that counts each line and another that counts how many doubles in the line.

Reading text File and putting it in a array

I am trying to take a set of 25 numbers from a text file and convert it into a array. But I am lost.
I have read some other questions similar to this, but all of them used imports and extras, and I don't want to use any imports besides import java.io.*; nor any list.
Also the for loop within this is method is me just messing with it, because I couldn't figure it out.
public static int[] processFile (String filename) throws IOException, FileNotFoundException {
BufferedReader inputReader = new BufferedReader (new InputStreamReader(new FileInputStream(filename)));
String line;
int[] a = new int[25];
while (( line = inputReader.readLine()) != null){
int intValue = Integer.parseInt(line); //converts string into int
for (int i = 0; i < a.length; i++){
a[intValue]++;
}
}
return a;
}
public static void printArray (int[] a) {
for (int i = 0; i<a.length; i++) {
System.out.println (a[i]);
}
}
public static void main(String[] args) throws IOException, FileNotFoundException {
int [] array = processFile("C:\Users\griff_000\Desktop\TestWeek13.txt");
printArray(array);
}
I'm unclear about your whole import restriction, why exactly are you trying to limit the number of imports you have?
Anyway, looking at your code, it seems like the concept of arrays isn't all that clear with you.
Arrays are accessed under the syntax:
array[index] = value;
looking at your code, the line a[intValue]++; is actually finding the array index intValue (the number read from file) and incrementing it by one. Not only is this not what you want, numbers over the array length will cause an ArrayIndexOutOfBoundsException.
Making said amendments we get:
public static int[] processFile (String filename) throws IOException, FileNotFoundException{
BufferedReader inputReader = new BufferedReader (new InputStreamReader(new FileInputStream(filename)));
String line;
int[] a = new int[25];
int i = 0; // We need to maintain our own iterator when using a while loop
while((line = inputReader.readLine()) != null){
int intValue = Integer.parseInt(line); //converts string into int
a[i] = intValue; // Store intValue into the array at index i
i++; // Increment i
}
return a;
}
note the additional variable i being used in this context to facilitate the incrementing index number being used to access the array. If you examine this method carefully, a input file longer than 25 elements would also throw ArrayIndexOutOfBoundsException due to the variable i becoming 25 (beyond the limits of the array). To fix, I'd suggest changing the loop structure to a for-loop (assuming your input array is of fixed size) as follows:
public static int[] processFile (String filename) throws IOException, FileNotFoundException{
BufferedReader inputReader = new BufferedReader (new InputStreamReader(new FileInputStream(filename)));
String line;
int[] a = new int[25];
for(int i = 0; i < a.length; i++){
String line = inputReader.readLine(); // Move the readline code inside the loop
if(line == null){
// We hit EOF before we read 25 numbers, deal appropriately
}else{
a[i] = Integer.parseInt(line);
}
}
return a;
}
Note how the for loop integrates the iterator variable into one nice elegant line, keeping the rest of the code neat and readable.
Your mistake is in the line a[intValue]++;. You are telling Java to find the element at [intValue] and add 1 to it's current value. From your question, I understood that you want to put intValue as the array element.
Since you are using i as the iterator, to add the element simply use:
a[i] = intValue;
What you are doing here:
a[intValue]++;
is increasing the array position of the read value by one. If the number read is 2000 you are increasing a[2000]
you might want to do this
a[i]=intValue;

Simple issue about possible to re use java Scanner?

I am still new to java and is it possible to re use the Scanner object?
The below example is I am reading a file to do characters, words and lines count. I know there must be a better way to do counting with one scanner object only but that is not the main point. I just wonder why there is input.close() but no input.open() or input.reset etc.. Since I am actually reading the same file, is it possible to create only one Scanner object and pass for 3 methods to use? Thanks
public class Test {
/**
* #throws java.io.FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException {
File file = new File("demo.java");
Scanner input = new Scanner(file);
Scanner input2 = new Scanner(file);
Scanner input3 = new Scanner(file);
int lines = 0;
int words = 0;
int characters = 0;
checkCharacters(input3);
checkLines(input);
checkwords(input2);
}
private static void checkLines(Scanner input) {
int count = 0;
while (input.hasNext()) {
String temp = input.nextLine();
String result = temp;
count++;
}
System.out.printf("%d lines \n", count);
}
private static void checkwords(Scanner input2) {
int count = 0;
while (input2.hasNext()) {
String temp = input2.next();
String result = temp;
count++;
}
System.out.printf("%d words \n", count);
}
private static void checkCharacters(Scanner input3) {
int count = 0;
while (input3.hasNext()) {
String temp = input3.nextLine();
String result = temp;
count += temp.length();
}
System.out.printf("%d characters \n", count);
}
}
No, there's no way to reset the Scanner from a method on the Scanner. You might be able to do it if you passed in an InputStream into the scanner and then reset the stream directly but I don't think it's worth it.
You seem to be parsing the same file 3 times and processing the same input 3 times. That seems like a waste of processing. Couldn't you perform all 3 counts at once?
private static int[] getCounts(Scanner input) {
int[] counts = new int[3];
while(input.hasNextLine()){
String line = input.nextLine();
counts[0]++; // lines
counts[2]+=line.length(); //chars
//count words
//for simplicity make a new scanner could probably be better
//using regex or StringTokenizer
try(Scanner wordScanner = new Scanner(line)){
while (wordScanner.hasNext()) {
wordScanner.next();
count[1] ++; //words
}
}
}
return counts;
}
Of course the Object Oriented way would be to return a new object named something like Counts with methods to getNumLines(), getNumChars() etc.
EDIT
One thing to note, I kept the calculations the same as you had in the original question. I'm not sure if the counts will always be accurate especially characters since Scanner may not return all end of line characters so the chars count may be off and the number of lines may be off if there are consecutive blank lines? You would need to test this.
No it is not possible because as the documentation says
void close()
throws IOException
Closes this stream and releases any system resources associated with
it. If the stream is already closed then invoking this method has no
effect.
Once a resource is relaesed there is no way to get it back, untill you have a reference to it , which is actually closed

How do I return an array of words given an input sentence (string)?

How do I create a method that takes a string as an argument, and returns the array whose elements are the words in the string.
This is what I have came up with so far:
// split takes some string as the argument, and returns the array
// whose elements are the words in the string
public static String[] split (String s)
{
// determine the number of words
java.util.Scanner t = new java.util.Scanner (s);
int countWords = 0;
String w;
while (t.hasNext ())
{
w = t.next ();
countWords++;
}
// create appropriate array and store the string’s words in it
// code here
}
As you can see, I can just input each word via Scanner. Now I just have to put all the words of the String into an array as the elements. However, I'm not sure how to proceed.
You can use StringTokenizer in java to devide your string into words:
StringTokenizer st = new StringTokenizer(str, " ");
And your output st whould be an array of words.
Take a look at this Java StringTokenizer tutorial for further information.
Your code whould look like:
StringTokenizer st = new StringTokenizer(s, " ");
int n=st.countTokens();
for(int i=0;i<n;i++) {
words[i]=st.nextToken();// words is your array of words
}
As Maroun Maroun commented, you should use the split(regex) method from Strings, but if you want to do this by yourself:
First, declare the array:
String[] words = new String[50]; // Since you are using an array you have to declare
// a fixed length.
// To avoid this, you can use an ArrayList
// (dynamic array) instead.
Then, you can fill the array inside the while loop:
while (t.hasNext()) {
w = t.next();
words[countWords] = w;
countWords++;
}
And finally return it:
return words;
Note:
The sentences
words[countWords] = w;
countWords++;
can be simplified in
words[countWords++] = w;
As #Maroun Maroun said: use the split function or like #chsdk said use StringTokenizer.
If you want to use scanner:
public static String[] split(String s)
{
Scanner sc = new Scanner(s);
ArrayList<String> l = new ArrayList<String>();
while(sc.hasNext())
{
l.add(sc.next());
}
String[] returnValue = new String[l.size()];
for(int i = 0; i < returnValue.length; ++i)
{
returnValue[i] = l.get(i);
}
return returnValue;
}

Categories

Resources