(UPDATED)
I'm having trouble figuring out what to do here, i need to compare a 2d array that to see if any of the numbers match. I need four numbers to match either up/down, left/right, or diagonal. I just can't get it to test for the down/left diagonal ( / ) here is my updated code
public static boolean isAdjacentFour( int[][] a ) {
// Code to test if column has four adjacent numbers
for ( int row = 0; row <= a.length - 3 ; row++) {
for (int col = 0; col <= a[0].length - 1 ; col++) {
if (a[row][col] == a[row+1][col] && a[row+2][col] == a[row][col]
&& a[row+3][col] == a[row][col]) {
return true;
}
}
}
// Code to test if row has four adjacent numbers
for ( int row = 0; row <= a.length - 1 ; row++) {
for (int col = 0; col <= a[0].length - 3 ; col++) {
if (a[row][col] == a[row][col+1] && a[row][col] == a[row][col+2]
&& a[row][col] == a[row][col+3]) {
return true;
}
}
}
// Code to test if there are 4 adjacent numbers in a down/right ( \ )diagonal
for ( int row = 0; row <= a.length - 3 ; row++) {
for (int col = 0; col <= a[0].length - 3 ; col++) {
if (a[row][col] == a[row+1][col+1] && a[row][col] == a[row+2][col+2]
&& a[row][col] == a[row+3][col+3] ) {
return true;
}
}
}
for ( int row = 0; row <= a.length - 3 ; row++) {
for (int col = 0; col <= a[0].length + 3 ; col--) {
if (a[row][col] == a[row+1][col-1] && a[row][col] == a[row+2][col-2]
&& a[row][col] == a[row+3][col-3] ) {
return true;
}
}
}
return false;
}
Well one problem I noticed in the first nested for loop is this line of code,
for ( int row = 0; row <= a.length - 3 ; row++)
The way you have it now, the row variable is going to be incremented with each iteration of the outer for loop. However, with how you're executing your program, the condition should be row <= a.length - 4 and here's why. Suppose you had a four by four 2D array. The nested for loop will go through one normal iteration of the inner loop, which actually checks every single column for possible matches of four consecutive matching numbers in a column. Here's what it looks like when actually running the program starting at the outer for loop and row = 0,
Iteration One of the inner for loop:
if (a[0][0] == a[1][0] && a[2][0] == a[0][0] && a[3][0] == a[0][0])
Iteration Two of the inner for loop:
if (a[0][1] == a[1][1] && a[2][1] == a[0][1] && a[3][1] == a[0][1])
Iteration Three of the inner for loop:
if (a[0][2] == a[1][2] && a[2][2] == a[0][2] && a[3][2] == a[0][2])
Last Iteration of the inner for loop:
if (a[0][0] == a[1][3] && a[2][3] == a[0][3] && a[3][0] == a[0][3])
Once this is done, the row variable will be incremented according to the outer loop definition. This is what is most likely causing an error because now as we start iterating through the inner loop with row = 1, this happens
Iteration One of the inner for loop:
if (a[1][0] == a[2][0] && a[3][0] == a[1][0] && a[4][0] == a[1][0])
Here, we already have an indexoutofboundsexception when trying to access the 5th row in a 4x4 2D array. So the simple fix here is to change
for(int row = 0; row <= a.length - 3 ; row++)
to
for(int row = 0; row <= a.length - 4 ; row++)`
A similar argument can be made for the second nested for loop. If you don't believe me, do something similar to what I did for the rows and write out the iterations for it using a 4x4 2D array. You'll get the arrayindexoutofbounds exception in the first iteration of the outer for loop and in the second iteration of the inner for loop when row = 0 and col = 1, causing the program to make a check at the fifth column in the first row of a 2D array. So the simple fix should be to change
for (int col = 0; col <= a[0].length - 3 ; col++)
to
for (int col = 0; col <= a[row].length - 4 ; col++)
Personally, I prefer to use a[row].length only because there could be some instances where it's not a perfect nxn 2D array. For example, some rows may have only 3 columns where the first row has 7 columns. If this is the case, then you'll get an outofbounds exception for trying to access columns that exist in the first row that don't exist in other rows.
For the third nested for loop, again, same argument can be made just by writing out the iterations and it should be changed to
for(int row = 0; row <= a.length - 4 ; row++) {
for(int col = 0; col <= a[row].length - 4 ; col++)
The last nested for loop has a logic problem pertaining to the inner for loop. Since you're decrementing from 0, you're going to get an out of bounds exception just from trying to access negative indices in the array. So the simple fix should be to initialize col to the last column and change the condition to col being greater than or equal to 3 since you're accessing elements at the columns, col, col-1, col-2, and col-3. If that is confusing, think about it this way. You're checking columns starting from col and the three that come before it. What if there aren't even four columns to begin with? This is why there's the condition col >= 3 because you check a column and the three that come before it until you've reached column #4 (col = 3). Once you've reached column #3 (col = 2), there's no way of checking that column and the three before because there are only 3 columns to check at this point. Changes similar to the other 3 nested loops should be made to for ( int row = 0; row <= a.length - 3 ; row++) regarding the -3. It should end up looking like this,
for ( int row = 0; row <= a.length - 4 ; row++) {
for (int col = a[row].length - 1; col >= 3; col--)
As a rule of thumb , always put debug points to see why you are getting exception/error.
The issue here is your outer loop runs from 0 to row-1 . But inside in inner loop you are using [row+2] and [row+3] and [row+1] . Now when the outer loop goes to row-2 iteration , you will get a out of bound exception.
Can post the code here , but if you understand this , you should be able to solve it.
(EDIT) : example as asked in comment.
assume you have a 2D array A[][]of size 10X10 .
Now if the current loop is at A[4][4] or (A[row][col]) :
left element : A[4][3] or (A[row][col-1]) // here we are at same row but (column -1) as we want the left element.
top-right element : A[3][5] or ((A[row-1][col+1]) // here we are going to (4-1) row as we are interested in above row and (4+1)column as we want right element.
bottom-left: A[5][3] (A[row+1][col-1]) ...
Now the two consecutive bottom-left elements will be (A[row+1][col-1]) and (A[row+2][col-2]).
Try visualizing it by drawing a 2D array and naming each cell in terms of A[i][j].
Related
public static boolean absoluteSorted(int[][] mat) {
for (int i = 0; i < mat.length; i++) {
for (int j = 0; j < mat[i].length; j++) {
if(mat[i][j]<mat[mat.length-1][mat[i].length-1]) {
return true;
}
}
}
return false;
}
what is wrong with my code??
Example:
Input: Output:false Input: -5 0 5 Output:true
2 0 0 -2 9 12
8 6 0 9 10 20
4 5 8
what is wrong with my code?
If you want to check that the columns and rows are sorted, you need to compare all element with the next one in its column and the next one in its row.
Your code is comparing against the last element in each row and column.
Also, your code returns true on the first element that is "in order". It should only return when it has checked all elements that need checking.
My guess is that this line:
if(mat[i][j]<mat[mat.length-1][mat[i].length-1]) {
Should be something like:
if(mat[i][j] < mat[i-1][j-1]) { // Except when i or j == 0
Because "sorting" means comparing each cell in turn.
I am a beginner to Java--I want to construct a 2D array that takes votes as a user's input. I've been trying to make sure the user cannot enter "votes" for themself--I have tried using
&& col != row
In the for loop but this does not seem to work. My current for loop is this:
for (int row = 0; row < Vote.length; row++)
{
System.out.println("Enter "+ this.TeamMember[row]+"'s votes, points must add up to 100:");
System.out.println();
for (int col=0; col < this.Vote[row].length && col != row; col++ )
{
System.out.println("Enter "+this.TeamMember[row]+ "'s points for "+ this.TeamMember[col]+":");
this.Vote[row][col] = scan.nextInt();
}
Is there a way to skip data entries for when the row in a two-dimensional array equals the column?
Thanks for your help!
Try putting that condition inside the inner for loop
if(row != col){
// inner for loop
}
You can use an if-conditional and a continue statement to skip the current iteration of the for loop.
Inside your inner for loop, immediately check if (col == row), and if so, continue;.
EDIT: You should also take out the && col != row conditional in the inner for loop. That will kill your for loop early.
Below problem has a list of characters and number of columns as the input. Number of columns is not a constant and can vary with every input.
Output should have all the rows fully occupied except for the last one.
list: a b c d e f g
colums: 3
Wrong:
a b c
d e f
g
Wrong:
a d g
b e
c f
Correct:
a d f
b e g
c
I have tried below:
public static void printPatern(List<Character> list, int cols) {
for (int i = 0; i < cols; i++) {
for (int j = i; j < list.size(); j += cols) {
System.out.print(list.get(j));
}
System.out.println();
}
}
It gives output as (which is wrong):
a d g
b e
c f
I am trying to come with an algorithm to print the correct output. I want to know what are the different ways to solve this problem. Time and Space complexity doesn't matter. Also above method which I tried is wrong because it takes columns as the parameter but that's actually acting as the number of rows.
FYI: This is not a HOMEWORK problem.
Finally able to design the algorithm for this problem
Please refer below java code same
public class puzzle{
public static void main(String[] args){
String list[] = { "a", "b", "c","d","e","f","g","h","i","j" };
int column = 3;
int rows = list.length/column; //Calculate total full rows
int lastRowElement = list.length%column;//identify number of elements in last row
if(lastRowElement >0){
rows++;//add inclomplete row to total number of full filled rows
}
//Iterate over rows
for (int i = 0; i < rows; i++) {
int j=i;
int columnIndex = 1;
while(j < list.length && columnIndex <=column ){
System.out.print("\t"+list[j]);
if(columnIndex<=lastRowElement){
if(i==rows-1 && columnIndex==lastRowElement){
j=list.length; //for last row display nothing after column index reaches to number of elements in last row
}else{
j += rows; //for other rows if columnIndex is less than or equal to number of elements in last row then add j value by number of rows
}
}else {
if(lastRowElement==0){
j += rows;
}else{
j += rows-1; //for column greater than number of element in last row add j = row-1 as last row will not having the column for this column index.
}
}
columnIndex++;//Increase column Index by 1;
}
System.out.println();
}
}
}
This is probably homework; so I am not going to do it for you, but give you some hints to get going. There are two points here:
computing the correct number of rows
computing the "pattern" that you need when looping your list so that you print the expected result
For the first part, you can look into the modulo operation; and for the second part: start iterating your list "on paper" and observe how you are printing the correct result manually.
Obviously, that second part is the more complicated one. It might help if you realize that printing "column by column" is straight forward. So when we take your correct example and print the indexes instead of values, you get:
0 3 6
1 4 7
2 5
Do that repeatedly for different input; and you will soon discover the pattern of indexes that you need to print "row by row".
Assume I had a 2D integer array, mxn.
I want to traverse this array like a sine wave.
In specific, traversal would start from the last row, and the first column, move onto the first row and the second column, move onto the last row and the third column.
I have attached an image to elaborate further.
t:
I only know how to traverse in order, but I was thinking of transposing the columns, changing the starting index of the column at every round, but I couldn't create a consisting loop to do so.
My attempt:
boolean startsAtbottom=true;
//cols become rows, startPoint alternates
for(int i = 0;i<n;i++)
{
if(startsAtbottom)
{
for(int j =m-1;j>-1;j--)
{
System.out.print(myArr[j][i]);
}
startsAtbottom=false;
}
else
{
for(int j =0;j<m;j++)
{
System.out.print(myArr[j][i]);
}
startsAtbottom=true;
}
}
The following code will do what you want. All you want is to change the way you traverse in consecutive iterations.
boolean traverseInOrder=true;
for(int i=0;i<columnCount;i++){
for(int j=0;j<rowCount;j++){
index=j;
if(!traverseInOrder){
index=rowCount-j-1;
}
//access the element
int element=array[i][index];
}
traverseInOrder= !traverseInOrder;
}
Your solution works, and there's nothing wrong with it. However you can get rid of the if by doing this:
for (int i = 0; i < n; i++) {
boolean goingUp = i % 2 == 0;
for (int j = 0; j < m; j++) {
int row = goingUp ? m - 1 - j : j;
System.out.println(myArr[row][i]);
}
}
Starting from your input you have that:
the outer loop index just increments from 0
the inner loop index increments for even columns and decrements for odd columns
you can determine if a number is even or odd by just checking if modulo is 0 (or by checking if (i & 0x01) == 0 but that's irrelevant)
Given this it's quite easy to model that pattern:
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
int value = data[i][i % 2 == 0 ? (cols - j - 1) : j]
}
}
The formula cols - j - 1 allows you to start from the end and go backward (see that with j = 0 you have cols - 1 and with j = cols - 1 you have cols - (cols - 1) - 1 == 0).
Mind that Java is nor column major nor row major, since a bidimensional array is just an array of arrays so according to your real layout you may need to swap indices.
I want to add data to a dataset to display some values on a graph. On some files, the first line is a description of the columns (like "Timestamp" or something else). I need my code to test if the first line contains integer or float values and if not to skip this line and add data to dataset from 2nd line.
This is my code:
for (int i = 0; i < listOfLists.size(); i++) {
for (int j = 1; j < listOfLists.get(i).size(); j++) {
if (listOfLists.get(i).get(0).matches("\\d+(?:\\,\\d+)?") || listOfLists.get(i).get(0).matches("\\d+(?:\\.\\d+)?")) {
datasetBar.addValue(Float.parseFloat(listOfLists.get(i).get(j).replace(",",".")),columnsLabel[i].getText(), ""+listOfLists.get(0).get(j));
} else if(listOfLists.get(i).get(1).matches("\\d+(?:\\,\\d+)?") || listOfLists.get(i).get(1).matches("\\d+(?:\\.\\d+)?")){
datasetBar.addValue(Float.parseFloat(listOfLists.get(i).get(j).replace(",",".")),columnsLabel[i].getText(), ""+listOfLists.get(0).get(j));
The problem is that I get an error when he's trying to represent String on the plot of the bar chart
List of lists is a list of columns. Each column of the file is added into a list and each list into the listOfLists.
I tried to use on the else if block: listOfLists.get(i).remove(0) but it didn't worked. (in next loops it keeped removing the first line of the remaining list.
Thanks in advance!
You can check in the outer loop, before inner loop:
if (i == 0 && listOfLists.get(i).get(0).matches(/\\d+(?:[\\.,]\\d+)?)/) == false) {
continue; // skip first line
}
BTW: You should not call remove method while iterating list because you will get ConcurrentModificationException.
It could be something like this:
for (int i = 0; i < listOfLists.size(); i++) {
for (int j = 0; j < listOfLists.get(i).size(); j++) {
if (j==0){ // Only test if it is a string in position [0]
boolean isNumber = listOfLists.get(i).get(0).matches("\\d+(?:\\,\\d+)?") || listOfLists.get(i).get(0).matches("\\d+(?:\\.\\d+)?");
if (!isNumber) continue; // If it is not a number, skip it
}
// Add to database, because it is a number
datasetBar.addValue(Float.parseFloat(listOfLists.get(i).get(j).replace(",",".")),columnsLabel[i].getText(), ""+listOfLists.get(0).get(j));
Hope it will help anyone to understand.
for(int i = 0; i < n; i++){ /* i = 0 means position of i is 0 which is 1st line */
if(i != 0 ){ /* and as our purpose is skipping first line so I will only continue when i is not equal 0 like this we can skip first line in this if block */
continue;
}
}