A little lost on correct logic to make a subarray using for loops and not using the arrays class.
Cell[][] subArray = new Cell[10][78];
Cell[][] padded = makePaddedArray(message);
for (int i = 0; i < subArray.length; i++) {
for (int j = animationPattern; j < subArray[i].length + animationPattern; j++) {
subArray[i][j - animationPattern] = padded[i][j]; // out of bounds exception here -- column length?
}
}
Where animationPattern is an Integer equal to 1 for the most part and the padded array has the the dimensions [10][ ]. Also a cell is just an object.
I just honestly am looking for some clarification on how to make a subarray work here and the basis behind the out of bounds exception I'm receiving.
EDIT: makePaddedArray returns a 2D cell array with dimensions [10][x], where x is greater than or equal to 165.
Try changing this:
for (int i = 0; i < subArray.length; i++) {
for this:
for (int i = 0; i < subArray.length-1; i++) {
As you start from 0, and not from 1, you need to lower the end of the array also by 1.
Related
I started to read the famous "cracking the Coding Interview" book and I want to do the following exercice.
Write an algorithm such that if an element in an MxN matrix is 0, its entire row and column is set to 0.
Here is the author's solution :
public static void setZeros(int[][] matrix) {
int[] row = new int[matrix.length];
int[] column = new int[matrix[0].length];
// Store the row and column index with value 0
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length;j++) {
if (matrix[i][j] == 0) {
row[i] = 1;
column[j] = 1;
}
}
}
// Set arr[i][j] to 0 if either row i or column j has a 0
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if ((row[i] == 1 || column[j] == 1)) {
matrix[i][j] = 0;
}
}
}
}
I agree with the author about the main idea. We don't have to store the position of '0' in the matrix but only the position of the rows and columns that are concernerd. But what I found a little "strange" in her solution is that at the end, she did a loop on all the cells of the matrix, which is not necessary in my opinion.
Here is my solution :
static int[][] replaceMatrix(int[][] matrix){
int M = matrix.length;
int N = matrix[0].length;
boolean[] row = new boolean[M] ;
boolean[] column = new boolean[N];
for (int i =0; i< M; i++) {
for (int j = 0; j<N; j++ ){
if (matrix[i][j] == 0) {
row[i] = true;
column[j] = true;
}
}
}
for (int i =0; i<M; i++){
if (row[i]){
for (int k =0; k<N; k++){
matrix[i][k]=0;
}
}
}
for (int j =0; j<N; j++){
if (column[j]){
for (int k =0; k<M; k++){
matrix[k][j]=0;
}
}
}
I'am newbie in programmation so I'm not totaly sure about this. But in my solution, if we except the first step which is to store the 0 positions, my second part of my programme have a time complexity of O(M+N) while her solution has a complexity of O(M*N).
The problem is that the general complexity will be the same O(M*N + (M+N)) is the same that having the complexity O(2*M*N), no? (I'm not totally sure).
For example, if it's a matrix with M=N, so the two complexity of the two programs will be O(M^2).
I really want to know if there is a difference or not about complexity in this case?
ps : I read that the space complexity can be improved with a bit vector. But I really didn't understand. Can you just give me a general idea about it (in Java)?
Time complexity of your last two for loops is still O(M*N) as in worst case inner for loop will be running maximum value of k times.
There is technically no difference in your and the author's solution because both of you have traversed the entire matrix.So both codes are same ** if we have to consider big O notation**
In fact the author's code is a little bit( by little bit I do not mean a different time complexity) better. Here is the reason:
Suppose in your boolean array of rows, all rows are set true. Then in your case you will go through all rows and through each element of every row which is basically traversing the entire matrix.
Suppose in your boolean array of columns, all columns are set true. Then in your case you will go through all columns and through each element of every column which is basically traversing the entire matrix.
So you will in effect traverse the entire matrix twice. But the time complexity of the codes is the same because O(M*N) and O(2*M*N) is same.
You have already done saving space, since you used boolean data type.
while (scanner.hasNextLine()) {
line = scanner.nextLine();
if (line.charAt(0) != '#') {
c++;
//looking to get dimensions of line segments from file.
dimensions = new int[c][4];
//Split my file input into an array of tokens(strings)
tokens = line.split(",");
for (int i = 0; i < tokens.length; i++) {
//Parse strings to int.
dimtoke[i] = Integer.parseInt(tokens[i]);
for (int k = 0; k < dimensions.length; k++) {
for (int j = 0; j < dimensions[0].length; j++) {
//attempt to fill 2d array with contents from file.
dimensions[k][j] = dimtoke[j];
}
}
}
}
}
I get a 2d array full of the last dimension in the file instead of all the dimensions. The dimensions come in groups of 4 in a single line of text, so i made a single array with those tokens from each line i read in from the file so i could parse them to ints. something is happening in the process of transferring the 1d array of ints to the 2d array.
You have to close {} the tokens loop like this:
for (int i = 0; i < tokens.length; i++) {
//Parse strings to int.
dimtoke[i] = Integer.parseInt(tokens[i]);
}//you need a closing here
for (int k = 0; k < dimensions.length; k++) {
for (int j = 0; j < dimensions[0].length; j++) {
//attempt to fill 2d array with contents from file.
dimensions[k][j] = dimtoke[j];
}
}
I'll try to explain it to you.
Everytime you get an int in tokens with the instruction
dimtoke[i] = Integer.parseInt(tokens[i]);
Before getting the next int in dimtoke[i+1] you get into a loop where you fill all the ints in the 2d array with that dimitoke[i].
When those loops have finished(all the 2d array has been filled with only 1 int), you go again up and fill the dimitoke with the next int, and again, fill all the 2d array with that int.
What you need to do is to first finish the for loop and fill the dimitoke with the whole set of ints, and then, fill the 2D array with the ints in dimitoke.
Your problem was that you filled the whole array everytime you put an int in dimitoke, so everytime the whole 2d array was overwritten with only 1 int.
Another thing I expect to be wrong:
When you are filling the 2D array, you put the j variable in both dimensions and dimitoke, so if dimitoke lenght is not equal than the second array lenght of dimensions, you'll fill again every row with the same if dimitoke is greater, and indexOutOfBounds Excepcion if it's lesser. Here's an example:
dimitoke dimension = 10 = {0,1,2,3,4,5,6,7,8,9}
if dimensions have dimension 4, the output of dimensions will be:
0,1,2,3
0,1,2,3
0,1,2,3
.
.. c rows.
To repair that, what you can do is to change the dimitoke variable for a int n (for example) and change the code like this:
int n =0;
for (int k = 0; k < dimensions.length; k++) {
for (int j = 0; j < dimensions[0].length; j++) {
//attempt to fill 2d array with contents from file.
dimensions[k][j] = dimtoke[n];
n++;
}
}
I hope the error is out now
Not completely know what you want to do. But I think you should separate the two loop:
assign value to the dimtoke.
assign value to dimensions.
So I think apparently, you should enclose the loop here:
for (int i = 0; i < tokens.length; i++) {
//Parse strings to int.
dimtoke[i] = Integer.parseInt(tokens[i]);
}
I need to have the columns organized in increasing order. Right now I have the following done but, it is sorting the rows and not columns.Any help would be nice, ive been working on this all day. Thanks.
public static double[][] sortColumns(double[][] m) {
double[][] sortedArray = new double[m.length][m.length];
for (int i = 0; i < m.length; i++) {
double[] temp = new double[m.length];
for (int j = 0; j < m.length; j++) {
temp[j] = m[j][i];
}
Arrays.sort(temp);
for (int j = 0; j < temp.length; j++) {
sortedArray[j][i] = temp[j];
}
}
return sortedArray;
}
If you change
temp[j] = m[j][i];
to
temp[j] = m[i][j];
and
sortedArray[j][i] = temp[j];
to
sortedArray[i][j] = temp[j];
then your existing algorithm will work fine. It just means you'll be copying columns to your "temporary sorting area" instead of rows.
In your current solution, you are just mistaking on indexes, just like David Wallace tells you in his answer. I propose you a different answer, enumerating the possible solutions of this problem.
You have at least 4 solutions :
instead of storing your data like you are currently doing it, use the transponate of your matrix
implement yourself an efficient sorting algorithm that takes a bi-dimensional array and the index of a column in argument
at each turn of you loop, fill an array with the current column, sort it, and copy it back (if you don't care about using some additional memory, do it). That is what you are currently trying to do
transponate your matrix, sort its lines, transponate it back (if you don't want to use too much memory, use this)
I prefer the last solution, which code is :
public static double[][] sortColumns(double[][] m) {
double[][] sortedArray = new double[m.length][m.length];
// compute the transponate of m
for (int i=0 ; i<m.length ; i++)
for (int j=0 ; j<m[i].length ; j++)
sortedArray[j][i] = m[i][j];
// sort the lines of the transponate
for (int i=0; i<sortedArray.length; i++)
Arrays.sort(sortedArray[i]);
// transponate back the result of the sorting
for (int i=0 ; i<sortedArray.length ; i++)
for (int j=i+1 ; j<sortedArray[i].length ; j++) {
double tmp = sortedArray[i][j];
sortedArray[i][j] = sortedArray[j][i];
sortedArray[j][i] = tmp;
}
return sortedArray;
}
When I look at your code I see the following line:
double[][] sortedArray = new double[m.length][m.length];
it doesn't look right to me.
you need to find length and breath of the array so i would do something like this:
length = m.length;
breath = m[0].length;
if i m not sure of all rows have same no of elements i may do that check by a for loop and initialize with the max.. wud lead to memory wastage but thats another demon to tame :)
next when we write m[x][y] x represents the rows and y represents the columns so when ur doing :
for (int j = 0; j < m.length; j++) {
temp[j] = m[j][i];
}
Arrays.sort(temp);
you are fetching all the values from a column i, assigning it to temp array and sorting the column.
hope that helps
I am trying to replace rows from an original 2d array to a updated 2d array. Problem is it won't store the last element during the replacement.
Here's my code:
String[][] updatedArray = {{"red","a","b","c"},{"yellow","a","b","c"}, {"purple","a","b","c"}};
String[][] originalArray = {{"red","aa","bb","cc"},{"yellow","ww","vv","zz"}, {"green","yy","uu","pp"}, {"purple","nn","mm","bb","hello"}};
for (int i = 0; i < updatedArray.length;i++ ) {
for (int j = 0; j < updatedArray[i].length; j++){
for(int x = 0; x < originalArray.length;x++){
for(int z = 0; z < originalArray[x].length;z++){
if(originalArray[x][0].equals(updatedArray[i][0])) {
updatedArray[i][j] = originalArray[x][j];
System.out.println("There's a match!!");
}else{
System.out.println("No match!");
}
}
}
}
}
System.out.println("originalArray:");
System.out.println(Arrays.deepToString(originalArray));
System.out.println("updatedArray:");
System.out.println(Arrays.deepToString(updatedArray));
For example, initially updatedArray in last row "purple" has {"purple","a","b","c"}. When it does the replacement using values from originalArray, the code above only outputs:
... [purple, nn, mm, bb]
which is wrong because it doesn't add the last element "hello". It should output:
... [purple, nn, mm, bb, hello]
I am aware the problem is in this line:
updatedArray[i][j] = originalArray[x][j];
Problem is no matter what I try to change originalArray[x][j] to originalArray[x][z] ... its screws up everything.
Any ideas on this? Still trying to get the jist of 2D arrays.
If there is a match, instead of trying to set each element in the updatedArray to the corresponding element in the original array you can just set the entire array to the original array.
String[][] updatedArray = {{"red","a","b","c"},{"yellow","a","b","c"}, {"purple","a","b","c"}};
String[][] originalArray = {{"red","aa","bb","cc"},{"yellow","ww","vv","zz"}, {"green","yy","uu","pp"}, {"purple","nn","mm","bb","hello"}};
for (int i = 0; i < updatedArray.length;i++ ) {
for (int j = 0; j < originalArray.length; j++){
if(originalArray[j][0].equals(updatedArray[i][0])) {
updatedArray[i] = originalArray[j];
System.out.println("There's a match!!");
}else{
System.out.println("No match!");
}
}
}
The issue is how you chose to iterate over the dimensions of updatedArray which are different than the dimensions of originalArray.
Let just look at the case i=2 which is the 'row' for purple:
for (int j = 0; j < updatedArray[i].length; j++){
updatedArray[i=2].length = 4
in updated:
index = 0 , 1 , 2 , 3
{"purple","a","b","c"}
in original:
index = 0 , 1 , 2 , 3 , 4
{"purple","nn","mm","bb","hello"}
Therefore since j will always be < 4 it can never be used to index originalArray[x][4] = "hello"
DANGER: this code also doesn't handle the fact that you would need to extend the purple array for updatedArray. Java may do some magic to handle this for you but I wouldn't trust it to work that way.
Suggestion:
- compare the lengths of each row and allocate extra memory where necessary before copying data from originalArray to updatedArray
- if possible just copy the whole row between original and updated.
Thanks in advance for your feedback. I can't make sense of an ArrayIndexOutofBoundsException error in the snippet of code below. Is it obvious to any of you?
public void run() {
int x = 10;
int y = 10;
double[][] Lx = new double[x][y];
double[][] Ly = new double[x][y];
for (int i=0; i<Lx.length; i++) {
for (int j=0; j<Lx[0].length; i++) {
Lx[j][i] = 2*j+i-1;
Ly[j][i] = Math.sqrt(3)*(i-1);
}
}
}
Your j for loop is incorrect in incrementing i, not j. Change
for (int j=0; j<Lx[0].length; i++) {
to
for (int j=0; j<Lx[0].length; j++) {
In addition, your array access indices are backwards. Change
Lx[j][i]
to
Lx[i][j]
and likewise with Ly. Otherwise you'll get a flipped 2D array.
With addition to #rgettman's answer
As in here your x and y is same so you will not have any issue with Lx[0].length. But it is good to use Lx[i].length.
Lx[0].length will always give the length or number of columns present in the 0th row. But Lx[i].length will give the length or number of columns present in the ith row.
So in case your x and y differs you will not again get ArrayIndexOutBoundException.
It should be j++ not i++ in the nested for-loop.
It's better not to use i and j for the index because they look too similar.
i and k are much more distinct than i and j