Why is in this program BufferedReader taking infinite input?
Below is the code which is taking input infinitely. To avoid this I have added condition
while((!(s1=br.readLine().trim()).equals(null))&&(!s1.isEmpty())){
but it didn't work out.
import java.io.*;
import java.util.*;
public class skylerStudent {
public static void main(String []args)throws IOException{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String s1="";String s="";
while((!(s1=br.readLine().trim()).equals(null))&&(!s1.isEmpty())){
s+=s1.trim()+" ";
}
StringTokenizer st=new StringTokenizer(s.trim());
int i=0,n=0,q=0;
while(st.hasMoreTokens()){
if(i==0)n=Integer.parseInt(st.nextToken());
if(i==1)q=Integer.parseInt(st.nextToken());
i++;
}
int ar[]=new int[n];i=0;
while(st.hasMoreTokens()){
if(i<n)ar[i]=Integer.parseInt(st.nextToken());
i++;
}
i=0;
while(st.hasMoreTokens()){
StringTokenizer st1=new StringTokenizer(st.nextToken());
while(st.hasMoreTokens()){
if(i<q){
int a=Integer.parseInt(st1.nextToken());
int b=Integer.parseInt(st1.nextToken());
System.out.println(a);System.out.println(b);}
i++;
}
}
}
}
The condition !(s1 = br.readLine().trim()).equals(null) is not correct. If you can call .trim on string then it can never be null. You can check
(s1 = br.readLine()) != null
Also the infinite loop is not in the reading the input, its in the one of the later loops of the code.
while (st.hasMoreTokens()) {
if (i == 0)
n = Integer.parseInt(st.nextToken());
if (i == 1)
q = Integer.parseInt(st.nextToken());
i++;
}
You are not moving forward to nextToken() if the i is not in (0,1). That's why it would never exit the loop.
Related
It's the first time I'm doing this so I didn't want to be lengthy. I'm building a cross reference from reading a java program. I'm to exclude java keywords, commented words and words in quotations. I got through with excluding the java keywords and the commented words but I'm having problems excluding those in quotes.
public class CrossReference {
static Scanner in;
static PrintWriter out;
static int currentLine = 0;
public static void main(String[] args) throws IOException {
in = new Scanner (new FileReader("keywords.txt"));
out = new PrintWriter (new FileWriter("crossreference.out"));
LinkedList keywords = new LinkedList();
while (in.hasNextLine()) {
String word = in.nextLine();
keywords.addTail(new NodeData(word));
}
in = new Scanner (new FileReader("program.txt"));
BinaryTree bst = new BinaryTree();
while(in.hasNextLine()){
String line = in.nextLine();
out.printf("%3d. %s\n", ++currentLine,line);
getWordsOnLine(line,bst,keywords);
}
out.printf("\nWords LineNumber\n\n");
bst.inOrder();
out.close();
}
public static void getWordsOnLine(String inputLine, BinaryTree bst, LinkedList keywords){
Scanner inLine = new Scanner(inputLine);
inLine.useDelimiter("[^a-zA-Z//\"*]+");
boolean b = true;
while(inLine.hasNext() && b){
String word = inLine.next().toLowerCase();
if (word.contains("/") || word.contains("\"") || word.contains("*")) {
b = false;
} //this works for the commented words but not so well for the ones in quotes as it also excludes words after those in quotes
else {
boolean key = false;
Node curr = keywords.head;
while (curr != null) {
if (curr.data.str.equals(word)) key = true;
curr = curr.next;
}
if (key == false) {
TreeNode node = bst.findOrInsert(new TreeNodeData(word));
ListNode p = new ListNode(currentLine);
p.next = node.data.firstLine;
node.data.firstLine = p;
}
}
}
}
}
Split your string by space into an array.
Iterate through the array, checking which elements start with quotes and are words
Sum it
So the code would look like:
public class HelloWorld
{
public static void main(String[] args)
{
String a = "COPY PASTE ORIGINAL HERE";
String[] arr = a.split(" ");
int count = 0;
for(String each: arr){
if(each.charAt(0) != '\"' && each.charAt(0) < '0' || each.charAt(0) > '9'){
count++;
}
}
System.out.println("words="+count);
}
}
I have come across a problem. I need to implement stack with push and pop operations.
Input
The first line of the input file contains a single integer number N (1 <= N <= 10^6) – the number of test cases.
Next N lines tells about operations. + means push. - means pop. I need to print popped element.
Example
Input Output
6
+ 1 10
+ 10 1234
-
+ 2
+ 1234
-
I have written following code
public class Main {
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(new File("stack.in"));
PrintWriter pw = new PrintWriter(new File("stack.out"));
int n=sc.nextInt();
int[] stack = new int[n]; int i=0;
while(n-->0) {
String s = sc.next();
if(s.equals("+")) {
stack[i++]=sc.nextInt();
} else {
pw.println(stack[--i]);
}
}
sc.close(); pw.close();
}
}
This program is giving me Time Limit Exceeded.
Please suggest me an efficient algorithm to solve this.
For each input file:
Time limit: 2 seconds
Memory limit: 256 megabytes
A rule of thumb: if you're solving a competitive programming style problem and the input is large (say, 10^5 numbers or more), the Scanner is too slow.
You can use a StringTokenizer on top of a BufferedReader to speed up the input.
It can look like this:
class FastScanner {
private StringTokenizer tokenizer;
private BufferedReader reader;
public FastScanner(InputStream inputStream) {
reader = new BufferedReader(new InputStreamReader(inputStream));
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
String line;
try {
line = reader.readLine();
} catch (IOException e) {
throw new RuntimeException(e);
}
if (line == null)
return null;
tokenizer = new StringTokenizer(line);
}
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
}
This should be a simple question, but I'm struggling with it. Everything in my code is working except for initializing the parameter values for "train_rows" and "cols" read in from the Configuration file.
I set up logging to display the values of "train_rows" and "cols" within the setup() method, and the values were correct. However, when I tried the same thing within the map() method, both values showed 0. What am I doing wrong?
import java.io.File;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.Scanner;
import org.apache.log4j.Logger;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
public class KNNMapper extends Mapper<LongWritable, Text, IntWritable, IntWritable> {
private static final Logger sLogger = Logger.getLogger(KNNMapper.class);
private int[][] train_vals;
private int[] train_label_vals;
private int train_rows;
private int test_rows;
private int cols;
#Override
public void setup(Context context) throws IOException, InterruptedException {
Configuration conf = context.getConfiguration();
train_rows = conf.getInt("rows", -1);
cols = conf.getInt("columns", -1);
//just changed this
//int[][] train_vals = new int[train_rows][cols];
//int[] train_label_vals = new int[train_rows];
train_vals = new int[train_rows][cols];
train_label_vals = new int[train_rows];
// read train csv, parse, and store into 2d int array
Scanner myScan;
try {
File trainfile = new File("train_sample.csv");
if (!trainfile.exists()) {
throw new IllegalArgumentException("train file didn't load");
}
myScan = new Scanner(trainfile);
//Set the delimiter used in file
myScan.useDelimiter("[,\r\n]+");
//Get all tokens and store them in some data structure
//I am just printing them
for(int row = 0; row < train_rows; row++) {
for(int col = 0; col < cols; col++) {
train_vals[row][col] = Integer.parseInt(myScan.next().toString());
}
}
myScan.close();
} catch (FileNotFoundException e) {
System.out.print("Error: Train file execution did not work.");
}
// read train_labels csv, parse, and store into 2d int array
try {
File trainlabels = new File("train_labels.csv");
if (!trainlabels.exists()) {
throw new IllegalArgumentException("train labels didn't load");
}
myScan = new Scanner(trainlabels);
//Set the delimiter used in file
myScan.useDelimiter("[,\r\n]+");
//Get all tokens and store them in some data structure
//I am just printing them
for(int row = 0; row < train_rows; row++) {
train_label_vals[row] = Integer.parseInt(myScan.next().toString());
if(row < 10) {
System.out.println(train_label_vals[row]);
}
}
myScan.close();
} catch (FileNotFoundException e) {
System.out.print("Error: Train Labels file not found.");
}
}
#Override
public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
// setup() gave us train_vals & train_label_vals.
// Each line in map() represents a test observation. We iterate
// through every train_val row to find nearest L2 match, then
// return a key/value pair of <observation #,
// convert from Text to String
System.out.println("I'm in the map!");
String line = value.toString();
double distance;
double best_distance = Double.POSITIVE_INFINITY;
int col_num;
int best_digit = -1;
IntWritable rowId = null;
int i;
IntWritable rowNum;
String[] pixels;
System.out.println("Number of train rows:" + train_rows);
System.out.println("Number of columns:" + cols);
// comma delimited files, split on commas
// first we find the # of rows
pixels = line.split(",");
rowId = new IntWritable(Integer.parseInt(pixels[0]));
System.out.println("working on row " + rowId);
best_distance = Double.POSITIVE_INFINITY;
for (i = 0; i < train_rows; i++) {
distance = 0.0;
col_num = 0;
for (int j = 1; j < cols; j++) {
distance += (Integer.parseInt(pixels[j]) - train_vals[i][j-1])^2;
}
if (distance < best_distance) {
best_distance = distance;
best_digit = train_label_vals[i];
}
}
System.out.println("And we're out of the loop baby yeah!");
context.write(rowId, new IntWritable(best_digit));
System.out.println("Mapper done!");
}
}
i doubt this , assuming you are scanning the file in hdfs.
you used:
import java.io.File; File trainfile = new File("train_sample.csv");
in hadoop this is how we check for a file in hdfs :
try {
FileSystem fs = FileSystem.get(context.getConfiguration());
if (fs.exists(new Path("/user/username/path/of/file/inhdfs"))) {
System.out.println("File exists");
}
} catch (IOException e) {
e.printStackTrace();
}
I am reading bunch of integers separated by space or newlines from the standard in using Scanner(System.in).
Is there any faster way of doing this in Java?
Is there any faster way of doing this in Java?
Yes. Scanner is fairly slow (at least according to my experience).
If you don't need to validate the input, I suggest you just wrap the stream in a BufferedInputStream and use something like String.split / Integer.parseInt.
A small comparison:
Reading 17 megabytes (4233600 numbers) using this code
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext())
sum += scanner.nextInt();
took on my machine 3.3 seconds. while this snippet
BufferedReader bi = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = bi.readLine()) != null)
for (String numStr: line.split("\\s"))
sum += Integer.parseInt(numStr);
took 0.7 seconds.
By messing up the code further (iterating over line with String.indexOf / String.substring) you can get it down to about 0.1 seconds quite easily, but I think I've answered your question and I don't want to turn this into some code golf.
I created a small InputReader class which works just like Java's Scanner but outperforms it in speed by many magnitudes, in fact, it outperforms the BufferedReader as well. Here is a bar graph which shows the performance of the InputReader class I have created reading different types of data from standard input:
Here are two different ways of finding the sum of all the numbers coming from System.in using the InputReader class:
int sum = 0;
InputReader in = new InputReader(System.in);
// Approach #1
try {
// Read all strings and then parse them to integers (this is much slower than the next method).
String strNum = null;
while( (strNum = in.nextString()) != null )
sum += Integer.parseInt(strNum);
} catch (IOException e) { }
// Approach #2
try {
// Read all the integers in the stream and stop once an IOException is thrown
while( true ) sum += in.nextInt();
} catch (IOException e) { }
If you asking from competitive programming point of view, where if the submission is not fast enough, it will be TLE.
Then you can check the following method to retrieve String from System.in.
I have taken from one of the best coder in java(competitive sites)
private String ns()
{
int b = skip();
StringBuilder sb = new StringBuilder();
while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
sb.appendCodePoint(b);
b = readByte();
}
return sb.toString();
}`
You can read from System.in in a digit by digit way. Look at this answer: https://stackoverflow.com/a/2698772/3307066.
I copy the code here (barely modified). Basically, it reads integers, separated by anything that is not a digit. (Credits to the original author.)
private static int readInt() throws IOException {
int ret = 0;
boolean dig = false;
for (int c = 0; (c = System.in.read()) != -1; ) {
if (c >= '0' && c <= '9') {
dig = true;
ret = ret * 10 + c - '0';
} else if (dig) break;
}
return ret;
}
In my problem, this code was approx. 2 times faster than using StringTokenizer, which was already faster than String.split(" ").
(The problem involved reading 1 million integers of up to 1 million each.)
StringTokenizer is a much faster way of reading string input separated by tokens.
Check below example to read a string of integers separated by space and store in arraylist,
String str = input.readLine(); //read string of integers using BufferedReader e.g. "1 2 3 4"
List<Integer> list = new ArrayList<>();
StringTokenizer st = new StringTokenizer(str, " ");
while (st.hasMoreTokens()) {
list.add(Integer.parseInt(st.nextToken()));
}
In programming perspective this customized Scan and Print class is way better than Java inbuilt Scanner and BufferedReader classes.
import java.io.InputStream;
import java.util.InputMismatchException;
import java.io.IOException;
public class Scan
{
private byte[] buf = new byte[1024];
private int total;
private int index;
private InputStream in;
public Scan()
{
in = System.in;
}
public int scan() throws IOException
{
if(total < 0)
throw new InputMismatchException();
if(index >= total)
{
index = 0;
total = in.read(buf);
if(total <= 0)
return -1;
}
return buf[index++];
}
public int scanInt() throws IOException
{
int integer = 0;
int n = scan();
while(isWhiteSpace(n)) /* remove starting white spaces */
n = scan();
int neg = 1;
if(n == '-')
{
neg = -1;
n = scan();
}
while(!isWhiteSpace(n))
{
if(n >= '0' && n <= '9')
{
integer *= 10;
integer += n-'0';
n = scan();
}
else
throw new InputMismatchException();
}
return neg*integer;
}
public String scanString()throws IOException
{
StringBuilder sb = new StringBuilder();
int n = scan();
while(isWhiteSpace(n))
n = scan();
while(!isWhiteSpace(n))
{
sb.append((char)n);
n = scan();
}
return sb.toString();
}
public double scanDouble()throws IOException
{
double doub=0;
int n=scan();
while(isWhiteSpace(n))
n=scan();
int neg=1;
if(n=='-')
{
neg=-1;
n=scan();
}
while(!isWhiteSpace(n)&& n != '.')
{
if(n>='0'&&n<='9')
{
doub*=10;
doub+=n-'0';
n=scan();
}
else throw new InputMismatchException();
}
if(n=='.')
{
n=scan();
double temp=1;
while(!isWhiteSpace(n))
{
if(n>='0'&&n<='9')
{
temp/=10;
doub+=(n-'0')*temp;
n=scan();
}
else throw new InputMismatchException();
}
}
return doub*neg;
}
public boolean isWhiteSpace(int n)
{
if(n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1)
return true;
return false;
}
public void close()throws IOException
{
in.close();
}
}
And the customized Print class can be as follows
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class Print
{
private BufferedWriter bw;
public Print()
{
this.bw = new BufferedWriter(new OutputStreamWriter(System.out));
}
public void print(Object object)throws IOException
{
bw.append("" + object);
}
public void println(Object object)throws IOException
{
print(object);
bw.append("\n");
}
public void close()throws IOException
{
bw.close();
}
}
You can use BufferedReader for reading data
BufferedReader inp = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(inp.readLine());
while(t-->0){
int n = Integer.parseInt(inp.readLine());
int[] arr = new int[n];
String line = inp.readLine();
String[] str = line.trim().split("\\s+");
for(int i=0;i<n;i++){
arr[i] = Integer.parseInt(str[i]);
}
And for printing use StringBuffer
StringBuffer sb = new StringBuffer();
for(int i=0;i<n;i++){
sb.append(arr[i]+" ");
}
System.out.println(sb);
Here is the full version fast reader and writer. I also used Buffering.
import java.io.*;
import java.util.*;
public class FastReader {
private static StringTokenizer st;
private static BufferedReader in;
private static PrintWriter pw;
public static void main(String[] args) throws IOException {
in = new BufferedReader(new InputStreamReader(System.in));
pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
st = new StringTokenizer("");
pw.close();
}
private static int nextInt() throws IOException {
return Integer.parseInt(next());
}
private static long nextLong() throws IOException {
return Long.parseLong(next());
}
private static double nextDouble() throws IOException {
return Double.parseDouble(next());
}
private static String next() throws IOException {
while(!st.hasMoreElements() || st == null){
st = new StringTokenizer(in.readLine());
}
return st.nextToken();
}
}
Reading from disk, again and again, makes the Scanner slow. I like to use the combination of BufferedReader and Scanner to get the best of both worlds. i.e. speed of BufferredReader and rich and easy API of the scanner.
Scanner scanner = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
I am having problems with my remote device discovery code for bluetooth scanning.
It scans, and prints the MAC addresses if i uncomment the "system.out.print(devicesDiscovered);
But i want to be able to extract each MAC address from the Vector and place it in a String.
I have two differant FOR loops to do this, but neither of them seem to be executing.
Code:
import java.io.IOException;
import java.util.List;
import java.util.Vector;
import javax.bluetooth.*;
public class BluetoothDeviceDiscovery {
public static final Vector/*<RemoteDevice>*/ devicesDiscovered = new Vector();
public static void main() throws IOException, InterruptedException {
final Object inquiryCompletedEvent = new Object();
devicesDiscovered.clear();
final DiscoveryListener listener = new DiscoveryListener() {
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
devicesDiscovered.addElement(btDevice);
//
String testingAgain = devicesDiscovered.toString();
System.out.println("What?? : " + testingAgain);
/*
* As far as i know, the following two FOR loops do the same thing
* But both of them are not being executed...
*/
//Its not executing this...
for(int i=0; i< devicesDiscovered.size(); i++) {
System.out.println("test if this gets output");
String test = (String) devicesDiscovered.elementAt(i);
System.out.println("Test: " + test);
}
//Its not executing this....
for(int i=0; i> ((List) btDevice).size(); i++){
System.out.println("test if this gets output 1");
String testing = (String) devicesDiscovered.toString();
System.out.print("Test1: " + testing);
}
//Prints the MAC addresses [macaddress, macaddress, macaddress, etc]
// System.out.println(devicesDiscovered);
/*
* Now need to extract each macaddress from devicesDiscovered
* and convert from a Vector to a String
*/
}
public void inquiryCompleted(int discType) {
System.out.println("Device Inquiry completed!");
synchronized(inquiryCompletedEvent){
inquiryCompletedEvent.notifyAll();
}
}
public void serviceSearchCompleted(int transID, int respCode) {
}
public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
}
};
synchronized(inquiryCompletedEvent) {
boolean started = LocalDevice.getLocalDevice().getDiscoveryAgent().startInquiry(DiscoveryAgent.GIAC, listener);
if (started) {
System.out.println("wait for device inquiry to complete...");
inquiryCompletedEvent.wait();
System.out.println(devicesDiscovered.size() + " device(s) found");
}
}
}
}
Can anyone spot any reason(s) as to why these two for loops are not working?
Thanks a lot
- Ryan
In this line
//Its not executing this....
for(int i=0; i > ((List) btDevice).size(); i++) {
You have turned the > the wrong way... try
for(int i=0; i < ((List) btDevice).size(); i++) {
instead.
(The reason it doesn't iterate, is because the initial value, 0, is not greater than the size of the list!)
In your first loop:
//Its not executing this...
for(int i=0; i< devicesDiscovered.size(); i++) {
System.out.println("test if this gets output");
it must be the case that devicesDiscovered is empty. I suggest you do
System.out.println(devicesDiscovered.size());
before the loop to debug.
The execution of your code in my machine is the following:
BlueCove version 2.1.0 on bluez
wait for device inquiry to complete...
What?? : [...]
test if this gets output
Test: ...
Device Inquiry completed!
1 device(s) found
BlueCove stack shutdown completed
With the following for loop:
for(int i=0; i< devicesDiscovered.size(); i++)
{
System.out.println("test if this gets output");
String test = (String) devicesDiscovered.elementAt(i).toString();
System.out.println("Test: " + test);
}
I've noticed that you were testing which one of the for loops was generating the output that you wanted. I can say that the above one works but the second generates an exception. You are trying to cast a RemoteDevice object to a List and iterate through it (for(int i=0; i < ((List) btDevice).size(); i++)). That's the reason for not working and therefore the exception.