I have this test data:
public class InputTest {
#Before
public void setUp() throws Exception {
ByteArrayInputStream in = new ByteArrayInputStream("90 22 11 4 5\n".getBytes());
System.setIn(in);
}
and I need to read each digit from InputStream as an integer. I create this test:
#Test
public void read() throws IOException {
int c;
while ((c = System.in.read()) != '\n') {
int i = readInt(c);
if (i != -1)
System.out.print(i);
}
}
private static int readInt(int c) {
int ret = 0;
if (c >= '0' && c <= '9') {
return ret * 10 + c - '0';
}
return -1;
}
And I have this output: 90221145 - I print each int to console. But I need separate digits like in source string - 90 22 11 4 5
I can change it to:
#Test
public void read() throws IOException {
int c;
StringBuilder b = new StringBuilder();
while ((c = System.in.read()) != '\n') {
int i = readInt(c);
if (i != -1) {
b.append(i);
}else {
b.append(" ");
}
}
System.out.println(b.toString());
}
private static int readInt(int c) {
int ret = 0;
if (c >= '0' && c <= '9') {
return ret * 10 + c - '0';
}
return -1;
}
But I don't want to create StringBuilder on each step. How can I do it?
P.S I know about BufferedReader's readLine() method and StringTokinizer and this does not fit. I need to read bytes. I solve problems with storage this data and I need fast reading only.
It is an example of an interview task and I need to read a big array of values with memory constraints.
What about writing it to System.out while you read the data
#Test
public void read() throws IOException {
int c;
StringBuilder b = new StringBuilder();
while ((c = System.in.read()) != '\n') {
int i = readInt(c);
if (i != -1) {
System.out.print(""+i);
}else {
System.out.print(" ");
}
}
System.out.print("\n"); // end of line
}
Related
How can I read int values from console more efficiently (from memory) than this:
BufferedReader in ...
number = Integer.parseInt(in.readLine());
When I use readLine() and parse it to int, java create many String objects and сonsumes memory. I try to use Scanner and method nextInt() but this approach is also not that efficiently.
P.S I need read > 1000_000 values and I have memory limit.
EDIT Full code of task
import java.io.*;
public class Duplicate {
public static void main(String[] args) throws IOException {
int last = 0;
boolean b = false;
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(reader.readLine());
for (int i = 0; i < n; i++) {
int number =Integer.parseInt(reader.readLine());
if (number == 0 && !b) {
System.out.println(0);
b = true;
}
if (number == last) continue;
last = number;
System.out.print(last);
}
}
}
And Rewrite variant:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
public class Duplicate {
public static void main(String[] args) throws IOException {
int last = 0;
boolean b = false;
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int nextInt = getNextInt(reader);
for (int i = 0; i < nextInt; i++) {
int number = getNextInt(reader);
if (number == 0 && !b) {
System.out.println(0);
b = true;
}
if (number == last) continue;
b = true;
last = number;
System.out.println(last);
}
}
static int getNextInt(Reader in) throws IOException {
int c;
boolean negative = false;
do {
c = in.read();
if (!Character.isDigit(c)) {
negative = c == '-';
}
} while (c != -1 && !Character.isDigit(c));
if (c == -1) return Integer.MIN_VALUE;
int num = Character.getNumericValue(c);
while ((c = in.read()) != -1 && Character.isDigit(c)) {
num = 10 * num + Character.getNumericValue(c);
}
return negative ? -num : num;
}
}
Both options do not pass from memory (((
EDIT2 I try profiling
int number = getRandom(); and start with 1000000
once again launched the same
and splash GC
You can read from in one char at a time, checking if it's a digit, and then accumulating it into a number. Something like:
int getNextInt(Reader in) throws IOException {
int c;
boolean negative = false;
do {
c = in.read();
if (!Character.isDigit(c)) { negative = c == '-' };
} while (c != -1 && !Character.isDigit(c));
if (c == -1) return Integer.MIN_VALUE; // Some sentinel to indicate nothing found.
int num = Character.getNumericValue(c);
while ((c = in.read()) != -1 && Character.isDigit(c)) {
num = 10 * num + Character.getNumericValue(c);
}
return negative ? -num : num;
}
Ideone demo
Of course, this is incredibly primitive parsing. But you could perhaps take this code as a basis and adapt it as required.
You can use this FastScanner class
static class FastScanner {
private BufferedReader reader = null;
private StringTokenizer tokenizer = null;
public FastScanner(InputStream in) {
reader = new BufferedReader(new InputStreamReader(in));
tokenizer = null;
}
public String next() {
if (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public String nextLine() {
if (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
return reader.readLine();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken("\n");
}
public long nextLong() {
return Long.parseLong(next());
}
public int nextInt() {
return Integer.parseInt(next());
}
}
It is very commonly used on codeforces to read large input where Scanner class leads to TLE
This is originally authored by https://codeforces.com/profile/Petr
I use this InputReader on codeforces. Works pretty well for me on large input cases. You can extend this up to your use case. I came across this after getting TLE using Scanner and add functionalities if needed.
static class InputReader {
private final InputStream stream;
private final byte[] buf = new byte[1024];
private int curChar;
private int numChars;
public InputReader(InputStream stream) {
this.stream = stream;
}
private int read() {
try {
if (curChar >= numChars) {
curChar = 0;
numChars = stream.read(buf);
if (numChars <= 0)
return -1;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return buf[curChar++];
}
public int readInt() {
return (int) readLong();
}
public long readLong() {
int c = read();
while (isSpaceChar(c)) {
c = read();
if (c == -1) throw new RuntimeException();
}
boolean negative = false;
if (c == '-') {
negative = true;
c = read();
}
long res = 0;
do {
if (c < '0' || c > '9') throw new InputMismatchException();
res *= 10;
res += (c - '0');
c = read();
} while (!isSpaceChar(c));
return negative ? (-res) : (res);
}
public int[] readIntArray(int size) {
int[] arr = new int[size];
for (int i = 0; i < size; i++) arr[i] = readInt();
return arr;
}
private boolean isSpaceChar(int c) {
return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
}
}
I'm trying to understand one java code, here is the code
package RestClient;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.PrintStream;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;
public class Test {
public static void main(String[] args) {
InputStream inputStream = System.in;
System.out.println("Its done");
OutputStream outputStream = System.out;
InputReader in = new InputReader(inputStream);
OutputWriter out = new OutputWriter(outputStream);
TaskE solver = new TaskE();
solver.solve(1, in, out);
out.close();
}
static class TaskE {
static long[] dp;
static long[] sum;
static int n;
static SegmentTreeRMQ tree;
public void solve(int testNumber, InputReader in, OutputWriter out) {
System.out.println("2");
n = in.nextInt();
System.out.println("It always come Here");
int c = in.nextInt();
if (c == 1) {
out.println(0);
return;
}
int[] a = in.nextIntArray(n);
dp = new long[n];
sum = new long[n + 1];
for (int i = 1; i <= n; i++) {
sum[i] = sum[i - 1] + a[i - 1];
}
tree = new SegmentTreeRMQ();
tree.constructST(a, n);
out.println(comp(a, 0, n - 1, c));
}
private long comp(int[] a, int l, int r, int c) {
//System.out.println(l+" "+r);
if (r < l) return 0;
if (r == l && c == 1) return 0;
else if (r == l) return a[l];
if (dp[l] != 0) return dp[l];
int min = a[l];
long val = sum[r + 1] - sum[l];
val = Math.min(val, (a[l] + comp(a, l + 1, r, c)));
if (l + c <= n)
val = Math.min(val, sum[l + c] - sum[l] - tree.RMQ(n, l, l + c - 1) + comp(a, l + c, r, c));
//System.out.println("val:"+l+" "+val);
dp[l] = val;
return val;
}
}
static class InputReader {
private InputStream stream;
private byte[] buf = new byte[1024];
private int curChar;
private int numChars;
private InputReader.SpaceCharFilter filter;
public InputReader(InputStream stream) {
System.out.println("1");
this.stream = stream;
}
public int read() {
System.out.println("Its4");
System.out.println("numChars Near 4: " +numChars);
System.out.println("curChar Near 4: " +curChar);
if (numChars == -1) {
throw new InputMismatchException();
}
if (curChar >= numChars) {
curChar = 0;
try {
System.out.println("5");
numChars = stream.read(buf);
System.out.println("numChars: "+numChars);
System.out.println("Print: "+new String(new byte[]{ (buf[curChar]) }, "US-ASCII"));
} catch (IOException e) {
throw new InputMismatchException();
}
if (numChars <= 0) {
return -1;
}
}
System.out.println("curChar++: "+curChar);
return buf[curChar++];
}
public int nextInt() {
System.out.println("3");
int c = read();
System.out.println("c: "+c);
while (isSpaceChar(c)) {
System.out.println("6");
c = read();
}
int sgn = 1;
System.out.println("7");
if (c == '-') {
System.out.println("8");
sgn = -1;
c = read();
}
int res = 0;
do {
if (c < '0' || c > '9') {
throw new InputMismatchException();
}
System.out.println("9");
res = res*10;
res = res+c - '0';
c = read();
} while (!isSpaceChar(c));
return res * sgn;
}
public boolean isSpaceChar(int c) {
if (filter != null) {
System.out.println("here");
return filter.isSpaceChar(c);
}
return isWhitespace(c);
}
public static boolean isWhitespace(int c) {
return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
}
public int[] nextIntArray(int n) {
int[] array = new int[n];
for (int i = 0; i < n; ++i) array[i] = nextInt();
return array;
}
public interface SpaceCharFilter {
public boolean isSpaceChar(int ch);
}
}
static class SegmentTreeRMQ {
int[] st;
int minVal(int x, int y) {
return (x < y) ? x : y;
}
int getMid(int s, int e) {
return s + (e - s) / 2;
}
int RMQUtil(int ss, int se, int qs, int qe, int index) {
// If segment of this node is a part of given range, then
// return the min of the segment
if (qs <= ss && qe >= se)
return st[index];
// If segment of this node is outside the given range
if (se < qs || ss > qe)
return Integer.MAX_VALUE;
// If a part of this segment overlaps with the given range
int mid = getMid(ss, se);
return minVal(RMQUtil(ss, mid, qs, qe, 2 * index + 1),
RMQUtil(mid + 1, se, qs, qe, 2 * index + 2));
}
int RMQ(int n, int qs, int qe) {
// Check for erroneous input values
if (qs < 0 || qe > n - 1 || qs > qe) {
System.out.println("Invalid Input");
return -1;
}
return RMQUtil(0, n - 1, qs, qe, 0);
}
int constructSTUtil(int arr[], int ss, int se, int si) {
// If there is one element in array, store it in current
// node of segment tree and return
if (ss == se) {
st[si] = arr[ss];
return arr[ss];
}
// If there are more than one elements, then recur for left and
// right subtrees and store the minimum of two values in this node
int mid = getMid(ss, se);
st[si] = minVal(constructSTUtil(arr, ss, mid, si * 2 + 1),
constructSTUtil(arr, mid + 1, se, si * 2 + 2));
return st[si];
}
void constructST(int arr[], int n) {
// Allocate memory for segment tree
//Height of segment tree
int x = (int) (Math.ceil(Math.log(n) / Math.log(2)));
//Maximum size of segment tree
int max_size = 2 * (int) Math.pow(2, x) - 1;
st = new int[max_size]; // allocate memory
// Fill the allocated memory st
constructSTUtil(arr, 0, n - 1, 0);
}
}
static class OutputWriter {
private final PrintWriter writer;
public OutputWriter(OutputStream outputStream) {
writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
}
public OutputWriter(Writer writer) {
this.writer = new PrintWriter(writer);
}
public void close() {
writer.close();
}
public void println(long i) {
writer.println(i);
}
public void println(int i) {
writer.println(i);
}
}
}
Doubts:
1) InputReader is inner class of Test class, where SpaceCharFilter interface is created with one method declared. I have seen only where interface can be used by using implementation on class eg class implements Interface { implements methods}, but in this case it is setup with class's variable filter. May I know please how this functionality works in Java ?
2) In isSpaceChar(int c) method what is the significance of filter variable ? What type of values can come in filter variable ?
3) I'm running code with this input "10 2" then enter. Ideally it should go to filter!=null condition in isSpaceChar method while reading second character from input "0" from "10 2", but its not going, may I know please why ?
Can anyone help me to clear these doubts ?
this is what polymorhism is about: we define an interface and call the method(s) defined in it not caring about what the actual implementation is (but expecting the implementation matching the interfaces contract which is defined by the name of the interface, the names of the methods defined in it and any comments it may have).
it can hold an object that implements SpaceCharFilter.
This is because the variable filter never gets an object assigned.
Thus both, the interface and the variable are useless in this code.
Problem Link
By brute force I mean if I take 6 variables a,l,i,w,e,z for alphabet A,L,I,W,E,Z and count their number of occurrence apply condition as:
if(a<1||l<4||i<1||w<1||e<1||z<2)
{
System.out.println("NO");
}
else
System.out.println("YES");
What's wrong in that?
Here's my complete code and also I'm getting wrong answer.
import java.io.*;
public class Main {
public static void main(String asd[]) throws Exception {
Parser in = new Parser(System.in);
int t=in.nextInt();
while(t-->0)
{
int r=in.nextInt();
int c=in.nextInt();int a,l,i,z,w,e;
a=l=i=z=w=e=0;
for(int j=0;j<r;j++)
{
String s=in.next();
for(int k=0;k<s.length();k++)
{
char ch=s.charAt(k);
switch(ch)
{
case 'A':a++;break;
case 'L':l++;break;
case 'I':i++;break;
case 'Z':z++;break;
case 'W':w++;break;
case 'E':e++;break;
}
}
}
if(a<1||l<4||i<1||w<1||e<1||z<2)
{
System.out.println("NO");
}
else
System.out.println("YES");
}
}
}
// for inputting
class Parser {
final private int BUFFER_SIZE = 1 << 16;
private DataInputStream din;
private byte[] buffer;
private int bufferPointer, bytesRead;
public Parser(InputStream in) {
din = new DataInputStream(in);
buffer = new byte[BUFFER_SIZE];
bufferPointer = bytesRead = 0;
}
public long nextLong() throws Exception {
long ret = 0;
byte c = read();
while (c <= ' ') c = read();
boolean neg = c == '-';
if (neg) c = read();
do {
ret = ret * 10 + c - '0';
c = read();
} while (c > ' ');
if (neg) return -ret;
return ret;
}
//reads in the next string
public String next() throws Exception {
StringBuilder ret = new StringBuilder();
byte c = read();
while (c <= ' ') c = read();
do {
ret = ret.append((char) c);
c = read();
} while (c > ' ');
return ret.toString();
}
public int nextInt() throws Exception {
int ret = 0;
byte c = read();
while (c <= ' ') c = read();
boolean neg = c == '-';
if (neg) c = read();
do {
ret = ret * 10 + c - '0';
c = read();
} while (c > ' ');
if (neg) return -ret;
return ret;
}
private void fillBuffer() throws Exception {
bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
if (bytesRead == -1) buffer[0] = -1;
}
private byte read() throws Exception {
if (bufferPointer == bytesRead) fillBuffer();
return buffer[bufferPointer++];
}
}
Just because the matrix contains enough letters doesn't mean there's a path that puts them all in the right order.
For a simple example, consider
AILLZZWELL
You need an L adjacent to the A, but there is none.
Have you ever played the game "Boggle?" It's basically the same concept.
I'm currently trying and implementing my own custom O(N.lgN) solution of Dijkstra's using Adjacency Lists. Now if you are familiar with this algorithm (most likely you are), I was having trouble storing the tuple for each Vertex. If you have no clue what i'm talking about, have alook at: http://qr.ae/LoESY
Tuples can easily be stored in C++ using
pair <int,int>.
Anyways, i found a solution to that and came to know, against all odds, that a similar class DOES exist its called the 'AbstractMap.SimpleEntry' Class. Details are given here:
https://stackoverflow.com/a/11253710/4258892
Now that you've read it, this works almost the same as pair<> and suffices to store the Adjacent Edge as the key and Weight as the Value in the tuple.
Declaration: Map.Entry pair= new AbstractMap.SimpleEntry(1,2);
Now i have all the inputs in the form of tuples stored in an ArrayList for each vector. I planned on adding the tuples of the source entered to the TreeSet and sort them in ascending order wrt the weights (right?). However, if i just add these tuples to the TreeSet, I am throw an error:
Exception in thread "main" java.lang.ClassCastException:java.util.AbstractMap$SimpleEntry cannot be cast to java.lang.Comparable
Now i don't know how to implement a custom comparator for a TreeSet which sorts my values ascendingly (In Dijkstra's, the edge with least weight would come out first right?). Also, if not possible with TreeSet, could you provide me with a Priority Queue with a comparator implemented?
Even if you didn't follow, Here's my code. Hopefully you'll understand:
EDIT Code Edited as per suggestion from below answer
package GRAPH;
import java.io.*;
import java.util.*;
/**
* Created by Shreyans on 3/25/2015 at 7:26 PM using IntelliJ IDEA (Fast IO Template)
*/
class DIJKSTA_TRY
{
public static void main(String[] args) throws Exception
{
InputReader in = new InputReader(System.in);
OutputWriter out = new OutputWriter(System.out);
//Initializing Graph
List<ArrayList<AbstractMap.SimpleEntry<Integer,Integer>>>gr=new ArrayList<ArrayList<AbstractMap.SimpleEntry<Integer, Integer>>>();//AbstractMap.SimpleEntry<Integer,Integer> is similar to pair<int a,int b> in C++
System.out.println("Enter no of Vertices");
int v=in.readInt();
System.out.println("Enter no of Edges");
int e=in.readInt();
for(int i=0;i<=v;i++)//Initializing rows for each vertex
{
gr.add(new ArrayList<AbstractMap.SimpleEntry<Integer, Integer>>());
}
System.out.println("Enter <Vertex> <Adjacent Vertex> <Weight>");
for(int i=0;i<e;i++)
{
int a = in.readInt();
int b = in.readInt();
int c = in.readInt();
gr.get(a).add(new AbstractMap.SimpleEntry<Integer, Integer>(b, c));
}
out.printLine(gr);
System.out.printf("Enter Source");
int s=in.readInt();
Comparator<AbstractMap.SimpleEntry<Integer, Integer>> comparator=new WeightComparator();
TreeSet<AbstractMap.SimpleEntry<Integer, Integer>>ts=new TreeSet<AbstractMap.SimpleEntry<Integer, Integer>>(comparator);
for(AbstractMap.SimpleEntry<Integer, Integer> pair: gr.get(s))//Error:Exception in thread "main" java.lang.ClassCastException: java.util.AbstractMap$SimpleEntry cannot be cast to java.lang.Comparable
{
ts.add(pair);
}
out.printLine(ts);
{
out.close();
}
}
static public class WeightComparator implements
Comparator<AbstractMap.SimpleEntry<Integer, Integer>>
{
#Override
public int compare(AbstractMap.SimpleEntry<Integer, Integer> one,
AbstractMap.SimpleEntry<Integer, Integer> two)
{
return Integer.compare(one.getValue(), two.getValue());
}
}
//FAST IO
private static class InputReader
{
private InputStream stream;
private byte[] buf = new byte[1024];
private int curChar;
private int numChars;
private SpaceCharFilter filter;
public InputReader(InputStream stream)
{
this.stream = stream;
}
public int read()
{
if (numChars == -1)
throw new InputMismatchException();
if (curChar >= numChars)
{
curChar = 0;
try
{
numChars = stream.read(buf);
} catch (IOException e)
{
throw new InputMismatchException();
}
if (numChars <= 0)
return -1;
}
return buf[curChar++];
}
public int readInt()
{
int c = read();
while (isSpaceChar(c))
c = read();
int sgn = 1;
if (c == '-')
{
sgn = -1;
c = read();
}
int res = 0;
do
{
if (c < '0' || c > '9')
throw new InputMismatchException();
res *= 10;
res += c - '0';
c = read();
} while (!isSpaceChar(c));
return res * sgn;
}
public String readString()
{
int c = read();
while (isSpaceChar(c))
c = read();
StringBuilder res = new StringBuilder();
do
{
res.appendCodePoint(c);
c = read();
} while (!isSpaceChar(c));
return res.toString();
}
public double readDouble()
{
int c = read();
while (isSpaceChar(c))
c = read();
int sgn = 1;
if (c == '-')
{
sgn = -1;
c = read();
}
double res = 0;
while (!isSpaceChar(c) && c != '.')
{
if (c == 'e' || c == 'E')
return res * Math.pow(10, readInt());
if (c < '0' || c > '9')
throw new InputMismatchException();
res *= 10;
res += c - '0';
c = read();
}
if (c == '.')
{
c = read();
double m = 1;
while (!isSpaceChar(c))
{
if (c == 'e' || c == 'E')
return res * Math.pow(10, readInt());
if (c < '0' || c > '9')
throw new InputMismatchException();
m /= 10;
res += (c - '0') * m;
c = read();
}
}
return res * sgn;
}
public long readLong()
{
int c = read();
while (isSpaceChar(c))
c = read();
int sgn = 1;
if (c == '-')
{
sgn = -1;
c = read();
}
long res = 0;
do
{
if (c < '0' || c > '9')
throw new InputMismatchException();
res *= 10;
res += c - '0';
c = read();
} while (!isSpaceChar(c));
return res * sgn;
}
public boolean isSpaceChar(int c)
{
if (filter != null)
return filter.isSpaceChar(c);
return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
}
public String next()
{
return readString();
}
public interface SpaceCharFilter
{
public boolean isSpaceChar(int ch);
}
}
private static class OutputWriter
{
private final PrintWriter writer;
public OutputWriter(OutputStream outputStream)
{
writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
}
public OutputWriter(Writer writer)
{
this.writer = new PrintWriter(writer);
}
public void print(Object... objects)
{
for (int i = 0; i < objects.length; i++)
{
if (i != 0)
writer.print(' ');
writer.print(objects[i]);
}
}
public void printLine(Object... objects)
{
print(objects);
writer.println();
}
public void close()
{
writer.close();
}
public void flush()
{
writer.flush();
}
}
}
Enter Source1
[[], [2=3, 4=3], [3=4], [1=7], [3=2]]
[2=3]
EDIT Works. Thanks #rgettman
You received the error because the AbstractMap.SimpleEntry class doesn't implement Comparable. A TreeSet that isn't given a Comparator must assume that its elements are Comparable, but they aren't.
You were right to determine that you need to create a Comparator, to tell the TreeSet how to order the elements.
Create your own class that implements Comparator<AbstractMap.SimpleEntry<Integer, Integer>>. In the compare method, extract the weights and compare them.
public class WeightComparator implements
Comparator<AbstractMap.SimpleEntry<Integer, Integer>>
{
#Override
public int compare(AbstractMap.SimpleEntry<Integer, Integer> one,
AbstractMap.SimpleEntry<Integer, Integer> two)
{
return Integer.compare(one.getValue(), two.getValue());
}
}
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am going crazy with this problem!
My solution is in Java - I have tried different inputs and haven't been able to reproduce the alleged wrong answer. Maybe someone here could possibly point to my solutions bottlenecks?
The verdict I am getting from UVa judge is "Wrong Answer".
// FOUND THE SOLUTION - I WAS PRINTING null chars at the end of some lines ('\u0000').
The problem is solved by adding if(maze[j][i] != '\u0000') before calling bufferedWriter.write(maze[j][i]
Thanks to everyone!
The intial code:
import java.io.*;
class Main {
public static final int MAX_NUMBER_OF_LINES = 31;
public static final int MAX_NUMBER_OF_CHARACTERS_PER_LINE = 81;
public static char[][] maze;
public static boolean[][] visitedLocations;
public static int numberOfMazes;
public static int numberOfLines;
public static int numberOfChars;
public static BufferedReader bufferedReader;
public static BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(System.out));
public static void main(String args[]) throws IOException {
readFromStandardInput();
bufferedWriter.flush();
}
public static void readFromStandardInput() throws IOException {
bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String line;
numberOfMazes = Integer.parseInt(bufferedReader.readLine());
int lineCounter = 0;
while (numberOfMazes > 0) {
maze = new char[MAX_NUMBER_OF_CHARACTERS_PER_LINE][MAX_NUMBER_OF_LINES];
visitedLocations = new boolean[MAX_NUMBER_OF_CHARACTERS_PER_LINE][MAX_NUMBER_OF_LINES];
lineCounter = 0;
while ((line = bufferedReader.readLine()) != null) {
if (line.charAt(0) == '_') {
break;
} else {
constructArrayLineByLine(line, lineCounter);
}
lineCounter++;
}
numberOfLines = lineCounter;
solvePreviousMaze();
bufferedWriter.write(line);
numberOfMazes--;
if (numberOfMazes > 0) {
bufferedWriter.write("\n");
}
}
}
public static void solvePreviousMaze() throws IOException {
for (int i = 1; i < numberOfLines; i++) {
for (int j = 1; j < numberOfChars; j++) {
if (maze[j][i] == '*') {
floodTheMaze(i, j);
solutionToStandardOutput();
return;
}
}
}
}
public static void solutionToStandardOutput() throws IOException {
for (int i = 0; i < numberOfLines; i++) {
for (int j = 0; j < numberOfChars; j++) {
bufferedWriter.write(maze[j][i]);
}
bufferedWriter.write("\n");
}
}
public static void floodTheMaze(int i, int j) {
if (visitedLocations[j][i]) {
return;
} else {
visitedLocations[j][i] = true;
}
if (maze[j][i] == ' ' || maze[j][i] == '*') {
maze[j][i] = '#';
floodTheMaze(i, j - 1);
floodTheMaze(i - 1, j);
floodTheMaze(i + 1, j);
floodTheMaze(i, j + 1);
}
}
public static void constructArrayLineByLine(String line, int numberOfLine) {
numberOfChars = Math.max(numberOfChars, line.length());
for (int i = 0; i < line.length(); i++) {
maze[i][numberOfLine] = line.charAt(i);
}
}
}
One very clear bug in your solution is that you are printing extra 'space characters' in your solution which is probably not what the question asked. For example, in the first sample output, you are printing extra spaces in the lower 5 lines. You can solve this problem by using an arraylist of array to store the input and then output that arraylist.
Also, you should probably output a new line after every line of output. (You are not doing so for the last line of output.)
Here is a link to my accepted solution for this problem.
import java.io.*;
import java.math.*;
import java.util.*;
import java.lang.*;
public class Main{
public static InputStream inputStream = System.in;
public static OutputStream outputStream = System.out;
public static FastReader in = new FastReader(inputStream);
public static PrintWriter out = new PrintWriter(outputStream);
public static void main(String[] args)throws java.lang.Exception{
new Main().run();
out.close();
}
int N;
int M;
boolean[][] dfsNode;
StringTokenizer tk;
char[][] grid;
char[][] filled;
String[] sep;
void run()throws java.lang.Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine().trim());
sep = new String[N];
for(int i=0; i<N; i++){
ArrayList<char[]> al = new ArrayList<char[]>();
while(true){
String s = br.readLine();
if(s.contains("_")){
sep[i] = s;
break;
}
char[] arr = s.toCharArray();
al.add(arr);
}
grid = new char[al.size()][];
for(int j=0; j<al.size(); j++){
grid[j] = al.get(j);
}
// ArrayUtils.printGrid(grid);
int stari = -1;
int starj = -1;
for(int j=0; j<grid.length; j++){
for(int k=0; k<grid[j].length; k++){
if(grid[j][k] == '*'){
stari = j;
starj = k;
break;
}
}
}
dfsNode = new boolean[grid.length][];
filled = new char[grid.length][];
for(int j=0; j<grid.length; j++){
char[] arr = new char[grid[j].length];
for(int k=0; k<grid[j].length; k++){
arr[k] = grid[j][k];
}
filled[j] = arr;
dfsNode[j] = new boolean[grid[j].length];
}
fillColour(stari, starj);
for(int j=0; j<filled.length; j++){
for(int k=0; k<filled[j].length; k++){
if(filled[j][k] == '*'){
out.print(' ');
}else{
out.print(filled[j][k]);
}
}
out.println();
}
out.println(sep[i]);
}
}
void fillColour(int row, int col){
if(row<0 || row>=grid.length || col<0 || col>=grid[row].length){
return;
}
if(dfsNode[row][col]){
return;
}
// fill on border?
if(grid[row][col]!=' ' && grid[row][col]!='*'){
return;
}
filled[row][col] = '#';
dfsNode[row][col] = true;
fillColour(row-1, col);
fillColour(row+1, col);
fillColour(row, col-1);
fillColour(row, col+1);
}
}
class FastReader{
private boolean finished = false;
private InputStream stream;
private byte[] buf = new byte[1024];
private int curChar;
private int numChars;
private SpaceCharFilter filter;
public FastReader(InputStream stream){
this.stream = stream;
}
public int read(){
if (numChars == -1){
throw new InputMismatchException ();
}
if (curChar >= numChars){
curChar = 0;
try{
numChars = stream.read (buf);
} catch (IOException e){
throw new InputMismatchException ();
}
if (numChars <= 0){
return -1;
}
}
return buf[curChar++];
}
public int peek(){
if (numChars == -1){
return -1;
}
if (curChar >= numChars){
curChar = 0;
try{
numChars = stream.read (buf);
} catch (IOException e){
return -1;
}
if (numChars <= 0){
return -1;
}
}
return buf[curChar];
}
public int nextInt(){
int c = read ();
while (isSpaceChar (c))
c = read ();
int sgn = 1;
if (c == '-'){
sgn = -1;
c = read ();
}
int res = 0;
do{
if(c==','){
c = read();
}
if (c < '0' || c > '9'){
throw new InputMismatchException ();
}
res *= 10;
res += c - '0';
c = read ();
} while (!isSpaceChar (c));
return res * sgn;
}
public long nextLong(){
int c = read ();
while (isSpaceChar (c))
c = read ();
int sgn = 1;
if (c == '-'){
sgn = -1;
c = read ();
}
long res = 0;
do{
if (c < '0' || c > '9'){
throw new InputMismatchException ();
}
res *= 10;
res += c - '0';
c = read ();
} while (!isSpaceChar (c));
return res * sgn;
}
public String nextString(){
int c = read ();
while (isSpaceChar (c))
c = read ();
StringBuilder res = new StringBuilder ();
do{
res.appendCodePoint (c);
c = read ();
} while (!isSpaceChar (c));
return res.toString ();
}
public boolean isSpaceChar(int c){
if (filter != null){
return filter.isSpaceChar (c);
}
return isWhitespace (c);
}
public static boolean isWhitespace(int c){
return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
}
private String readLine0(){
StringBuilder buf = new StringBuilder ();
int c = read ();
while (c != '\n' && c != -1){
if (c != '\r'){
buf.appendCodePoint (c);
}
c = read ();
}
return buf.toString ();
}
public String nextLine(){
String s = readLine0 ();
while (s.trim ().length () == 0)
s = readLine0 ();
return s;
}
public String nextLine(boolean ignoreEmptyLines){
if (ignoreEmptyLines){
return nextLine ();
}else{
return readLine0 ();
}
}
public BigInteger nextBigInteger(){
try{
return new BigInteger (nextString ());
} catch (NumberFormatException e){
throw new InputMismatchException ();
}
}
public char nextCharacter(){
int c = read ();
while (isSpaceChar (c))
c = read ();
return (char) c;
}
public double nextDouble(){
int c = read ();
while (isSpaceChar (c))
c = read ();
int sgn = 1;
if (c == '-'){
sgn = -1;
c = read ();
}
double res = 0;
while (!isSpaceChar (c) && c != '.'){
if (c == 'e' || c == 'E'){
return res * Math.pow (10, nextInt ());
}
if (c < '0' || c > '9'){
throw new InputMismatchException ();
}
res *= 10;
res += c - '0';
c = read ();
}
if (c == '.'){
c = read ();
double m = 1;
while (!isSpaceChar (c)){
if (c == 'e' || c == 'E'){
return res * Math.pow (10, nextInt ());
}
if (c < '0' || c > '9'){
throw new InputMismatchException ();
}
m /= 10;
res += (c - '0') * m;
c = read ();
}
}
return res * sgn;
}
public boolean isExhausted(){
int value;
while (isSpaceChar (value = peek ()) && value != -1)
read ();
return value == -1;
}
public String next(){
return nextString ();
}
public SpaceCharFilter getFilter(){
return filter;
}
public void setFilter(SpaceCharFilter filter){
this.filter = filter;
}
public interface SpaceCharFilter{
public boolean isSpaceChar(int ch);
}
}