I was solving the Connected Sets problem on Amazon's Interview Street site https://amazon.interviewstreet.com/challenges and my code worked perfectly for the public sample test cases provided by the site, but I'm getting a NumberFormatException for the hidden test cases on line 25. Here is the part of my code that parses the input:
public class Solution
{
static int [][] arr;
static int num = 2;
static int N;
static String output = "";
public static void main(String[] args) throws IOException
{
int T;
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
T = Integer.parseInt(reader.readLine());
int i, j, k;
for(i=0;i<T;i++) //the loop for each of the 'T' test cases
{
N = Integer.parseInt(reader.readLine()); //line 25
arr = new int[N][N];
for(j=0;j<N;j++) //the loops for storing the input 2D array
{
for(k=0;k<N;k++)
{
arr[j][k] = Character.getNumericValue(reader.read());
reader.read();
}
}
I spent a lot of time trying to find what the problem is, but I've been unsuccessful at it. Thanks for your help in advance.
EDIT: The problem statement is given as follows on the site:
Given a 2–d matrix, which has only 1’s and 0’s in it. Find the total number of connected sets in that matrix.
Explanation:
Connected set can be defined as group of cell(s) which has 1 mentioned on it and have at least one other cell in that set with which they share the neighbor relationship. A cell with 1 in it and no surrounding neighbor having 1 in it can be considered as a set with one cell in it. Neighbors can be defined as all the cells adjacent to the given cell in 8 possible directions ( i.e N , W , E , S , NE , NW , SE , SW direction ). A cell is not a neighbor of itself.
Input format:
First line of the input contains T, number of test-cases.
Then follow T testcases. Each testcase has given format.
N [ representing the dimension of the matrix N X N ].
Followed by N lines , with N numbers on each line.
Output format:
For each test case print one line, number of connected component it has.
Sample Input:
4
4
0 0 1 0
1 0 1 0
0 1 0 0
1 1 1 1
4
1 0 0 1
0 0 0 0
0 1 1 0
1 0 0 1
5
1 0 0 1 1
0 0 1 0 0
0 0 0 0 0
1 1 1 1 1
0 0 0 0 0
8
0 0 1 0 0 1 0 0
1 0 0 0 0 0 0 1
0 0 1 0 0 1 0 1
0 1 0 0 0 1 0 0
1 0 0 0 0 0 0 0
0 0 1 1 0 1 1 0
1 0 1 1 0 1 1 0
0 0 0 0 0 0 0 0
Sample output:
1
3
3
9
Constraint:
0 < T < 6
0 < N < 1009
Note that the above sample test cases worked on my code. The hidden test cases gave the exception.
Okay, so I modified my program to incorporate LeosLiterak's suggestion to use trim() and the new code is as follows:
public class Solution
{
static int [][] arr;
static int num = 2;
static int N;
static String output = "";
public static void main(String[] args) throws IOException
{
int T;
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
T = Integer.parseInt(reader.readLine().trim());
int i, j, k;
for(i=0;i<T;i++)
{
N = Integer.parseInt(reader.readLine().trim());
arr = new int[N][N];
for(j=0;j<N;j++)
{
String [] temp = reader.readLine().trim().split(" ");
for(k=0;k<N;k++)
{
arr[j][k] = Integer.parseInt(temp[k]);
}
}
So instead of reading each character in the input matrix and converting it to an integer and storing, I now read the entire line and trim and split the string and convert each substring into an integer and store in my array.
Copied from comments: try to remove all white characters like spaces, tabulators etc. These characters are not prohibited by goal definition but they cannot be parsed to number. You must trim them first.
Check if its number before parse to int.
Character.isNumber()
T = Integer.parseInt(reader.readLine()); This where the problem. when user try to give string
and it convert into integer and run through loop? For eg : if user gives 'R' as char than how the integer conversion can happen and will the loop run further?? No right.
Related
i wrote the code correctly for 2D array hourglass problem.but it shows only one error.i did not know how to rectify it and also i dint know how it will work on negative numbers.how i can get 13 as output from my code.
Input (stdin)
1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 0 0 0
0 9 2 -4 -4 0
0 0 0 -2 0 0
0 0 -1 -2 -4 0
Your Output (stdout)
0
Expected Output
13
here is my code:
public class Solution {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int rows =sc.nextInt();
int column = sc.nextInt();
int[][] a = new int[rows][column];
for(int i=0;i<rows;i++){
for(int j=0;j<column;j++){
a[i][j]=sc.nextInt();
}
}
int sum=0,max=0;
for(int i=0;i<rows-2;i++){
for(int j=0;j<column-2;j++){
sum =(a[i][j]+a[i][j+1]+a[i][j+2]+a[i+1][j+1]+a[i+2][j]+a[i+2][j+1]+a[i+2][j+2]);
if(sum>max){
max = sum;
}
}
}
System.out.println(max);
}
}
In the stdin you haven't provided the rows and columns value as input. Your code works fine and gives the output 13.
For this particular problem, your stdin should be:
6 6
1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 0 0 0
0 9 2 -4 -4 0
0 0 0 -2 0 0
0 0 -1 -2 -4 0
Where the first line represents rows and columns. And will be assigned to:
int rows =sc.nextInt();
int column = sc.nextInt();
So what was the problem in your code?
Previously these were assigned 1 and 1 [the first two inputs] and took only 1 and 0 (the next two inputs) as the corresponding value. As a result, it couldn't satisfy the entry conditions in loop. hence the sum remained 0 and showed that as an output.
I need to create a 2D array from a text file for later use in some operations.
This is my file separated by a space" ":
0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0 1 0
And this is the code that I have:
import java.io.*;
public class TxtToArray{
public static void main(String args[]){
double[][] array = new double[100][100];
int x=0, y=0;
try{
BufferedReader in = new BufferedReader(new FileReader("E:\\Documents\\JavaPrograms\\TxtToArray\\src\\Array.txt"));
String bar;
while ((bar = in.readLine()) != null){
String[] values = bar.split(" ");
for (String str : values){
double str_double = Double.parseDouble(str);
array[x][y]=str_double;
y++;
}
x++;
}
in.close();
}catch( IOException ioException ) {
System.out.println("Something happened...");
}
}
}
Thanks! for the help
EDIT:
I have corrected some errors in what came to be the explanation and code syntax. If there are more let me know.
You never told us what the problem is, but one issue I see is that you are splitting each line of input on comma alone. This won't work because your input data also uses space as a delimeter. One option is to remove this whitespace before splitting by comma:
while ((bar = in.readLine()) != null) {
String[] values = bar.replaceAll("\\s+", "")
.split(",");
for (int y=0; y < values.length; ++y) {
double str_double = Double.parseDouble(values[y]);
array[x][y] = str_double;
}
x++;
}
You will notice that I used a for loop to iterate over the strings in each input. This is a nice option because it eliminates the need for you to manage the second index of your array.
Your numers in the file are not only seperated by ,, but also by whitespaces. Double.parseDouble throws an exception, if this whitespace is included in the parameter. Therefore you need to use a regex that also matches these chars too, e.g. ,\s*. Also you need to set y back to 0 at the beginning of every iteration of the while loop:
while ((bar = in.readLine()) != null){
String[] values = bar.split(",\\s*");
y = 0;
for (String str : values){
double str_double = Double.parseDouble(str);
array[x][y] = str_double;
y++;
}
x++;
}
I have come across a problem statement to find the all the common sub-strings between the given two sub-strings such a way that in every case you have to print the longest sub-string. The problem statement is as follows:
Write a program to find the common substrings between the two given strings. However, do not include substrings that are contained within longer common substrings.
For example, given the input strings eatsleepnightxyz and eatsleepabcxyz, the results should be:
eatsleep (due to eatsleepnightxyz eatsleepabcxyz)
xyz (due to eatsleepnightxyz eatsleepabcxyz)
a (due to eatsleepnightxyz eatsleepabcxyz)
t (due to eatsleepnightxyz eatsleepabcxyz)
However, the result set should not include e from
eatsleepnightxyz eatsleepabcxyz, because both es are already contained in the eatsleep mentioned above. Nor should you include ea, eat, ats, etc., as those are also all covered by eatsleep.
In this, you don't have to make use of String utility methods like: contains, indexOf, StringTokenizer, split and replace.
My Algorithm is as follows: I am starting with brute force and will switch to more optimized solution when I improve my basic understanding.
For String S1:
Find all the substrings of S1 of all the lengths
While doing so: Check if it is also a substring of
S2.
Attempt to figure out the time complexity of my approach.
Let the two given strings be n1-String and n2-String
The number of substrings of S1 is clearly n1(n1+1)/2.
But we have got to find the average length a substring of S1.
Let’s say it is m. We’ll find m separately.
Time Complexity to check whether an m-String is a substring of an
n-String is O(n*m).
Now, we are checking for each m-String is a substring of S2,
which is an n2-String.
This, as we have seen above, is an O(n2 m) algorithm.
The time required by the overall algorithm then is
Tn=(Number of substrings in S1) * (average substring lengthtime for character comparison procedure)
By performing certain calculations, I came to conclusion that the
time complexity is O(n3 m2)
Now, our job is to find m in terms of n1.
Attempt to find m in terms of n1.
Tn = (n)(1) + (n-1)(2) + (n-2)(3) + ..... + (2)(n-1) + (1)(n)
where Tn is the sum of lengths of all the substrings.
Average will be the division of this sum by the total number of Substrings produced.
This, simply is a summation and division problem whose solution is as follows O(n)
Therefore...
Running time of my algorithm is O(n^5).
With this in mind I wrote the following code:
package pack.common.substrings;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class FindCommon2 {
public static final Set<String> commonSubstrings = new LinkedHashSet<String>();
public static void main(String[] args) {
printCommonSubstrings("neerajisgreat", "neerajisnotgreat");
System.out.println(commonSubstrings);
}
public static void printCommonSubstrings(String s1, String s2) {
for (int i = 0; i < s1.length();) {
List<String> list = new ArrayList<String>();
for (int j = i; j < s1.length(); j++) {
String subStr = s1.substring(i, j + 1);
if (isSubstring(subStr, s2)) {
list.add(subStr);
}
}
if (!list.isEmpty()) {
String s = list.get(list.size() - 1);
commonSubstrings.add(s);
i += s.length();
}
}
}
public static boolean isSubstring(String s1, String s2) {
boolean isSubstring = true;
int strLen = s2.length();
int strToCheckLen = s1.length();
if (strToCheckLen > strLen) {
isSubstring = false;
} else {
for (int i = 0; i <= (strLen - strToCheckLen); i++) {
int index = i;
int startingIndex = i;
for (int j = 0; j < strToCheckLen; j++) {
if (!(s1.charAt(j) == s2.charAt(index))) {
break;
} else {
index++;
}
}
if ((index - startingIndex) < strToCheckLen) {
isSubstring = false;
} else {
isSubstring = true;
break;
}
}
}
return isSubstring;
}
}
Explanation for my code:
printCommonSubstrings: Finds all the substrings of S1 and
checks if it is also a substring of
S2.
isSubstring : As the name suggests, it checks if the given string
is a substring of the other string.
Issue: Given the inputs
S1 = “neerajisgreat”;
S2 = “neerajisnotgreat”
S3 = “rajeatneerajisnotgreat”
In case of S1 and S2, the output should be: neerajis and great
but in case of S1 and S3, the output should have been:
neerajis, raj, great, eat but still I am getting neerajis and great as output. I need to figure this out.
How should I design my code?
You would be better off with a proper algorithm for the task rather than a brute-force approach. Wikipedia describes two common solutions to the longest common substring problem: suffix-tree and dynamic-programming.
The dynamic programming solution takes O(n m) time and O(n m) space. This is pretty much a straightforward Java translation of the Wikipedia pseudocode for the longest common substring:
public static Set<String> longestCommonSubstrings(String s, String t) {
int[][] table = new int[s.length()][t.length()];
int longest = 0;
Set<String> result = new HashSet<>();
for (int i = 0; i < s.length(); i++) {
for (int j = 0; j < t.length(); j++) {
if (s.charAt(i) != t.charAt(j)) {
continue;
}
table[i][j] = (i == 0 || j == 0) ? 1
: 1 + table[i - 1][j - 1];
if (table[i][j] > longest) {
longest = table[i][j];
result.clear();
}
if (table[i][j] == longest) {
result.add(s.substring(i - longest + 1, i + 1));
}
}
}
return result;
}
Now, you want all of the common substrings, not just the longest. You can enhance this algorithm to include shorter results. Let's examine the table for the example inputs eatsleepnightxyz and eatsleepabcxyz:
e a t s l e e p a b c x y z
e 1 0 0 0 0 1 1 0 0 0 0 0 0 0
a 0 2 0 0 0 0 0 0 1 0 0 0 0 0
t 0 0 3 0 0 0 0 0 0 0 0 0 0 0
s 0 0 0 4 0 0 0 0 0 0 0 0 0 0
l 0 0 0 0 5 0 0 0 0 0 0 0 0 0
e 1 0 0 0 0 6 1 0 0 0 0 0 0 0
e 1 0 0 0 0 1 7 0 0 0 0 0 0 0
p 0 0 0 0 0 0 0 8 0 0 0 0 0 0
n 0 0 0 0 0 0 0 0 0 0 0 0 0 0
i 0 0 0 0 0 0 0 0 0 0 0 0 0 0
g 0 0 0 0 0 0 0 0 0 0 0 0 0 0
h 0 0 0 0 0 0 0 0 0 0 0 0 0 0
t 0 0 1 0 0 0 0 0 0 0 0 0 0 0
x 0 0 0 0 0 0 0 0 0 0 0 1 0 0
y 0 0 0 0 0 0 0 0 0 0 0 0 2 0
z 0 0 0 0 0 0 0 0 0 0 0 0 0 3
The eatsleep result is obvious: that's the 12345678 diagonal streak at the top-left.
The xyz result is the 123 diagonal at the bottom-right.
The a result is indicated by the 1 near the top (second row, ninth column).
The t result is indicated by the 1 near the bottom left.
What about the other 1s at the left, the top, and next to the 6 and 7? Those don't count because they appear within the rectangle formed by the 12345678 diagonal — in other words, they are already covered by eatsleep.
I recommend doing one pass doing nothing but building the table. Then, make a second pass, iterating backwards from the bottom-right, to gather the result set.
Typically this type of substring matching is done with the assistance of a separate data structure called a Trie (pronounced try). The specific variant that best suits this problem is a suffix tree. Your first step should be to take your inputs and build a suffix tree. Then you'll need to use the suffix tree to determine the longest common substring, which is a good exercise.
I'm trying to read a file and generate a 2D Array. So I believe my constructor will create the correct dimensions, I just don't know how to input the actual values into the arrays.
File format:
6
1 4 2 2 2 3
4 2 2 4 1 2
2 1 3 4 3 2
1 3 3 2 6 2
0 0 0 2 0 0
3 4 0 0 0 0
0 0 0 1 0 0
0 1 0 0 0 0
0 0 0 0 0 6
5 0 1 0 0 4
The file input is on the left, and the board result should look like the right :
6 | 1 4 2 2 2 3
1 4 2 2 2 3 | -----------
4 2 2 4 1 2 | 1|. . . 2 . .|4
2 1 3 4 3 2 | 3|3 4 . . . .|2
1 3 3 2 6 2 | 3|. . . 1 . .|2
0 0 0 2 0 0 | 2|. 1 . . . .|4
3 4 0 0 0 0 | 6|. . . . . 6|1
0 0 0 1 0 0 | 2|5 . 1 . . 4|2
0 1 0 0 0 0 | -----------
0 0 0 0 0 6 | 2 1 3 4 3 2
5 0 1 0 0 4 |
this first line of the file is the size of the board (6x6).
The second line is the "North to South(NS)" facing values
The third line is the "East to West(EW)" facing values
The fourth line is the "South to North(SN)" facing values
The fifth line is the "West to East(WE)" facing values.
And the rest of the lines will populate the board. A 0 will put nothing in.
public static final int EMPTY = 0;
int[][] board;
int dim;
int[] NS, SN, EW, WE; //the outter arrays
public SkyscraperConfig(Scanner f){
while(f.hasNextLine()){
if(f.nextLine().length() == 1){
dim = f.nextInt();
}
else{
outterArrays = f.nextLine().length();
}
}
this.board = new int[dimension+1][dimension+1];//I made the dimension +1 to hold the outter arrays that hold the NS, SN, EW, and WE values
this.NS = new int[outterArrays+1];
this.SN = new int[outterArrays+1];
this.EW = new int[outterArrays+1];
this.WE = new int[outterArrays+1];
}
My Idea was to create a 2D Array that is the size of the first line in the file. Then for the outer values, create four arrays which will represent the outside. I don't know how to put those outer arrays into my 2D array though.
As with all file reading, try to separate each task distinct task. Ask yourself "What do I need to know before I do , and what do I have to do in order to complete ?" Hopefully the tasks are listed in order (each task only requires information above it in the file), which is the case for your problem.
Your task seems to involve three sub tasks:
Figure out how large the arrays and matrix need to be (1 line)
Read in the side arrays (4 lines)
Read in the matrix (N lines)
So let's work with that:
int[][] board;
int dim;
int[] NS, SN, EW, WE; //the outter arrays
public SkyscraperConfig(Scanner f){
//First line should be dimension line
int dim = Integer.parseInt(f.nextLine());
//Initalize data structures based off of this dimension
this.NS = new int[dim];
this.SN = new int[dim];
this.EW = new int[dim];
this.WE = new int[dim];
this.board = new int[dim][dim];
//Read in side arrays
//...
//Read in the board
//...
}
Here we can guess that we're going to have a lot of duplicated code in reading the lines - probably time to start designing helper methods. One thing we seem to be doing a lot of is reading in a line and parsing all of the ints in it. So let's write a method for that
private static int[] parseIntLine(String line){
String[] arr = line.trim().split(' '); //Split on the space character
int[] intArr = new int[arr.length];
for(int i = 0; i < arr.length; i++){
intArr[i] = Integer.parseInt(arr[i]);
}
return intArr;
}
Now we can use this method to finish up our implementation, letting the reading take care of the array length:
public SkyscraperConfig(Scanner f){
//First line should be dimension line
int dim = Integer.parseInt(f.nextLine());
//Only actual initialization we have to do is for the matrix's outer array
board = new int[dim][];
//Read in side arrays
NS = parseIntLine(f.nextLine());
EW = parseIntLine(f.nextLine());
SN = parseIntLine(f.nextLine());
WE = parseIntLine(f.nextLine());
//Read in the board - dim rows to read
for(int i = 0; i < dim; i++){
board[i] = parseIntLine(f.nextLine());
}
f.close();
}
Now there's a lot of things that could go wrong that you should probably account for. What if the first line contains more than just one number? What if the first line contains a non-integer value? What if one of the side arrays or one of the board rows is of the wrong length? What if there aren't enough rows to fill the board? What if there are too many rows? For each of these questions you should either handle the case within the method (via try/catch or if-else logic) or if it's an unfixable problem throw some kind of exception.
I've been struggling on this for some time and I'm really confused on how to solve this problem.
I've found something that works with MatLab but it's not what I need.
Here's my scenario:
private int[][] c = {{1,1,1,1,1,1,1},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0}
};
c is a matrix in which I can have only one value set to 1 in each column.
This means that a configuration like
private int[][] c = {{0,1,0,1,1,0,0},
{1,0,0,0,0,1,1},
{0,0,1,0,0,0,0}
};
is valid, while
private int[][] c = {{1,0,1,1,0,1,1},
{0,0,1,0,0,0,0},
{0,0,0,0,1,0,0}
};
is not.
What I need is to generate a Set containing all the valid combinations for this matrix, but I've no idea on how to start.
I don't know if it's just because it's late and I'm half asleep but I can't think of a good way to do this.
Do you have any ideas?
There are many possible ways of actually implementing this. But you basically have to count from 0 to 37, and create one matrix for each number.
Imagine each possible column of the matrix as one number:
1
0 = 0
0
0
1 = 1
0
0
0 = 2
1
Then, the matrices can be represented by numbers in 3-ary form. The number 0000000 will correspond to the matrix
1 1 1 1 1 1 1
0 0 0 0 0 0 0
0 0 0 0 0 0 0
The number 0000001 will correspond to the matrix
1 1 1 1 1 1 0
0 0 0 0 0 0 1
0 0 0 0 0 0 0
and so on.
Then, you can compute the total number of matrices, count up from 0 to this number, convert each number into a string in 3-ary form, and fill the matrix based on this string.
The 895th matrix will have the number 1020011, which is one of your example matrices:
0 1 0 1 1 0 0
1 0 0 0 0 1 1
0 0 1 0 0 0 0
A simple implementation:
public class MatrixCombinations
{
public static void main(String[] args)
{
int cols = 7;
int rows = 3;
int count = (int)Math.pow(rows, cols);
for (int i=0; i<count; i++)
{
String s = String.format("%"+cols+"s",
Integer.toString(i, rows)).replaceAll(" ", "0");
int[][] matrix = createMatrix(rows, cols, s);
System.out.println("Matrix "+i+", string "+s);
printMatrix(matrix);
}
}
private static int[][] createMatrix(int rows, int cols, String s)
{
int result[][] = new int[rows][cols];
for (int c=0; c<cols; c++)
{
int r = s.charAt(c) - '0';
result[r][c] = 1;
}
return result;
}
private static void printMatrix(int matrix[][])
{
for (int r=0; r<matrix.length; r++)
{
for (int c=0; c<matrix[r].length; c++)
{
System.out.printf("%2d", matrix[r][c]);
}
System.out.println();
}
}
}