Why does this result in a infinite loop? - java

I am trying to program a method that will use Gauss Elimination on a matrix (2 dimensional array), and I'm trying to debug my method and I've encountered this problem
public int Gauss() {
int i = 1;
int j = 1;
int pivotCol = 0;
while (pivotCol == 0 && j <= cols())
if (i == rows()){
j ++;
i = 1;
}
if (get(i,j) == 1.0){
pivotCol = j;
} else {
i ++;
}
return pivotCol;
}
This is not the final method, but for some reason, this loop never ceases, why?

while (pivotCol == 0 && j <= cols()) {
...
}
You forgot the brackets, so the while is only working with the if statement and therefore its running infinite.

I guess the problem is that your while loop doesn't have curly braces, e.g. it's effectively as follows:
while (pivotCol == 0 && j <= cols()) {
if (i == rows()){
j++;
i = 1;
}
}
If i != rows() this will never terminate.

Related

Printing only NON-BOUNDARY and CORNER elements of an (n*n) array

I am to write a program that prints ONLY the NON-BOUNDARY AND CORNER elements of an (n*n) array, for my assignment, and this is the main part of the code:
The output I am getting is this:
As you can see, the non-boundary elements (6,7,10,11) are not in their correct positions, which I believe, is because of incorrect printing of tab spaces within the loop. (My code is totally a mess) I would like some help or suggestions to fix this. Thanks!
I generally find that flattening things (the if-conditions in particular), and putting conditions into boolean-returning methods helps. Try something like
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++ {
if (isCorner(i,j,n) || !isEdge(i,j,n)) {
//...
} else {
//...
}
}
System.out.println();
}
where isCorner(i,j,n) and isEdge(i,j,n) are defined something like
public boolean isCorner(int row, int column, int gridSize) {
//...
}
A you got a solution, just missing spaces, I'll add some smart things:
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
boolean visible = (i % (n - 1) == 0) == (j % (n - 1) == 0);
if (visible) {
System.out.printf(" %4d", a[i][j]);
} else {
System.out.print(" ");
}
}
System.out.println();
}
No longer any problems with tabs "\t", though I used spaces here.
Keep it simple, too many cases just cause problems - as you experienced.
The trick here is to consider whether to print or not. Hence I started with
a variable visible.
The border condition
i == 0 || i == n - 1
could also be written with modulo as
i % (n - 1) == 0
If this is "too smart", hard to grasp reading:
boolean iOnBorder = i % (n - 1) == 0;
boolean jOnBorder = j % (n - 1) == 0;
boolean visible = iOnBorder == jOnBorder;
The "X" pattern checks the _equivalence of i-on-border and j-on-border.
For the rest: formatted printf allows padding of a number.
Try this i have optimized your if condition
No need to again check for i == 0 or i == n-1
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i==0 || i==n-1){
if(j==0 || j==n-1){
System.out.print(a[i][j]);
}
}else{
if(j != 0 && j!= n-1){
System.out.print(a[i][j]);
}
}
System.out.print("\t");
}
System.out.println();
}
Just gave a try in case you might find it helpful.
public static void main(String[] args) throws ParseException {
int[][] ar = new int[4][4];
int[] input = new int[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
int pointer=0;
int imin=0,jmin=0,imax=3,jmax=3;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
ar[i][j]=input[pointer];
pointer++;
}
}
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(!((i==imax && j==jmin)||(i==imin && j==jmax)||i==j) && //For skipping the corners
(i == imin || j == jmin || i == imax || j == jmax)){// Not to print the borders
continue;
}
else {
System.out.println(ar[i][j]);
}
}
}
}

what can cause this particular palindrome a logic error

The following method was written to determine whether its String parameter reads identically left-to-right and right-to-left (the so called palindrome). I am having trouble finding the logic error of this palindrome. I believe the error is that the two conditions in the whole loop can affect checking the characters in the string. Please correct me if I am wrong so I can propose a proper solution.
This may be a stupid question to many of you, but I am new to java programming and this is written question on paper not actual code if that makes sense.
Your logic will only work if the length of input string is an odd number, i.e. 1,3,5 etc.
Because in case the length is even, i will never be equal to j. Example for a string "abba":
while (i == j && S.charAt(i) == S.charAt(j)) { // i = 0, j = 3
i++;
j--;
}
iteration-2:
while (i <= j && S.charAt(i) == S.charAt(j)) { // i = 1 , j = 2
i++;
j--;
}
iteration-3:
while (i <= j && S.charAt(i) == S.charAt(j)) { // i = 2 , j = 1
i++;
j--;
}
This will finally result in StringIndexOutOfBoundsException when i reaches negative value and j reaches a value greater than length of string.
Try below code:
static boolean isPalidrome(String s) {
int i = 0;
int j = s.length() - 1;
while( i <= j && s.charAt(i) == s.charAt(j)) {
i ++;
j--;
}
return i >= j;
}
your code will fail if input string is something like "zz" or "xxxx" meaning even length with same characters so ideally you can try with something like this :
public static boolean isPal(String str) {
int start = 0;
int end = str.length() - 1;
while (start < end) {
final char f = str.charAt(start++);
final char b = str.charAt(end--);
if (f != b) {
return false;
}
}
return true;
}
You may apply following changes in your own code. There are basically two changes which are in your termination condition of while loop i.e. i <= j and return condition of (i >= j)
public static boolean isPalindrome(String S) {
int i = 0, j = S.length() - 1;
while (i <= j && S.charAt(i) == S.charAt(j)) {
i++;
j--;
}
return (i >= j);
}

Method stuck in for Loop with If Conditional

I am trying to check several entries in a game board by iterating over them in a specific order.
Now what I noticed is that when the method is called by my junit test, it is stuck in the first for loop and doesn't continue with the next ones, and just returns false, meaning it jumps to the end of the method.
When I run a test which just needs the first 3 loops, then it works, but another test requires the second loop, which doesn't get executed.
Question: Why is it jumping to the end without first checking the other loops?
public boolean hasDiagonal(Mark m) {
for (int i = 0; i <= dimension-4; i++) {
for (int j = 0; j <= dimension-4; j++) {
for (int k = dimension-1; k == 3; k--) {
if (getField(i , j , k ) == m &&
getField(i+1, j+1, k-1) == m &&
getField(i+2, j+2, k-2) == m &&
getField(i+3, j+3, k-3) == m) {
return true;
//Stops here, if this part doesn't yield true,
//it returns false immediately
}
}
}
}
//This doesn't get checked
for (int i = dimension-1; i == 3; i--) {
for (int j = 0; j <= dimension-4; j++) {
for (int k = dimension-1; k <= 3; k--) {
if (getField(i , j , k ) == m &&
getField(i-1, j+1, k-1) == m &&
getField(i-2, j+2, k-2) == m &&
getField(i-3, j+3, k-3) == m) {
return true;
}
}
}
}
return false;
}
I suspect that the i == 3 and k == 3 in your loop conditions are at least contributing to your problem. With these conditions the loops will get skipped unless dimension == 4.
The condition part of your loops should be the problem here -
for (int i = 0; i <= dimension-4; i++) {
for (int j = 0; j <= dimension-4; j++) {
for (int k = dimension-1; k == 3; k--)
the innermost loop executes only if dimension == 4 and since there is no modification within the loops to this variable.
The outermost and second loop doesn't even iterate more than once (the block would execute only once) if you do a j++ or i++ and at the same time check if i/j <= dimension(4)-4 resolving as i/j <= 0.
So certainly the loops need better handling with dimension specified and the conditions modified accordingly.

What's the effect of changing this condition in this Java function to find palindromes?

I am wondering how changing this condition will change the way the function works:
public static boolean palindrome(String str) {
int i = 0;
int j = str.length() - 1;
while(i < j) { // This condition
if(str.charAt(i) != str.charAt(j)) {
return false;
}
i = i + 1;
j = j - 1;
}
return true;
}
Changing it as follows:
public static boolean palindrome(String str) {
int i = 0;
int j = str.length() - 1;
while(i <= j) { // Change is here
if(str.charAt(i) != str.charAt(j)) {
return false;
}
i = i + 1;
j = j - 1;
}
return true;
}
They seem to both detect palindromes. The second one takes one more step. I don't see how this changes anything.
Thank you!
Between while(i < j) and while(i <= j) The difference is that the second one has one additional step because in the end, you are comparing i with j as suppose just everything less than j
Example with input abcba:
// First Code Indices Checked (i and j)
0 < 4
1 < 3
2 < 2 //fails, done
// Second Code Indices Checked (i and j)
0 <= 4
1 <= 3
2 <= 2 //passes, continues
3 <= 1 //fails, done, unneeded comparison
And just like #azurefrog said : "You don't have to check past the
midpoint in palindrome detection"

Minesweeper game blocks around the mines

Hi so I'm building a program to create the classical minesweeper game in Java, and have almost everything down but I cant figure out how to check the sqaures around a mine and to write in the numbers (i.e. if there are one, two, three mines next to it). I only included the method it's under, but I can post the rest of the program if necessary. What should my approach be? Thanks!
private void countAdjacentMines()
{
for (int i = 0; i < mineField.length; i++)
{
for (int j = 0; j < mineField.length; j++)
{
if (!(mineField[i][j].getIsMine()))
{
mineField[i-1][j-1];
mineField[i-1][j];
mineField[i-1][j+1];
mineField[i][j-1];
mineField[i][j+1];
mineField[i+1][j-1];
mineField[i+1][j];
mineField[i+1][j+1];
mineField[i][j].setAdjacentMines(0);
}
} // end for loop rows
} // end for loop columns
} // end countAdjacentMines
Something like this:
private void countAdjacentMines()
{
for (int i = 0; i < mineField.length; i++)
{
for (int j = 0; j < mineField.length; j++)
{
if (!(mineField[i][j].getIsMine()))
{
int count = 0;
for (int p = i - 1; p <= i + 1; p++)
{
for (int q = j - 1; q <= j + 1; q++)
{
if (0 <= p && p < mineField.length && 0 <= q && q < mineField.length)
{
if (mineField[p][q].getIsMine())
++count;
}
}
}
mineField[i][j].setAdjacentMines(count);
}
} // end for loop rows
} // end for loop columns
} // end countAdjacentMines
For each item in that "list", do something like:
if ((i-1) >= 0 && (j-1) >= 0 && mineField[i-1][j-1].getIsMine()) {
numAdjacentMines++;
}
It's probably worth writing a helper function to do all of this, and then you just need to call it 8 times.
You're on the right track. You should be keeping a counter, that represents the count of adjacent mines that return true for .getIsMine().
if (!(mineField[i][j].getIsMine()))
{
counter = 0;
if (i-1 >= 0)
{
if (j-1 >=0 && mineField[i-1][j-1].getIsMine()) counter++;
if (mineField[i-1][j].getIsMine()) counter++;
if (j+1 < mineField.length && mineField[i-1][j+1].getIsMine()) counter++;
}
if (j-1 >=0 && mineField[i][j-1].getIsMine()) counter++;
if (j+1 < mineField.length && mineField[i][j+1].getIsMine()) counter++;
if (i+1 < mineField.length)
{
if (j-1 >=0 && mineField[i+1][j-1].getIsMine()) counter++;
if (mineField[i+1][j].getIsMine()) counter++;
if (j+1 < mineField.length && mineField[i+1][j+1].getIsMine()) counter++;
}
mineField[i][j].setAdjacentMines(counter);
}
You also need to be checking that all of those values (i-1, j-1, i+1, j+1) don't go outside the bounds of your array (i - 1 > -1, etc)
EDIT:: I think I covered all of the checks.
I'm not sure what you're trying to do. This statement, mineField[i-1][j-1]; and the ones like it just access data and do nothing with it.
I'm assuming that the array stores something that includes a boolean that tells you whether or not there's a mine in that space. If that's true, just make a counter and change those statements to something like if(mineField[i-1][j-1].hasMine()) counter++;. And then change the last statement to mineField[i][j].setAdjacentMines(counter);.
int sum = 0;
sum += mineField[i-1][j-1].getIsMine() ? 1 : 0;
sum += mineField[i-1][j].getIsMine() ? 1 : 0;
sum += mineField[i-1][j+1].getIsMine() ? 1 : 0;
sum += mineField[i][j-1].getIsMine() ? 1 : 0;
sum += mineField[i][j+1].getIsMine() ? 1 : 0;
sum += mineField[i+1][j-1].getIsMine() ? 1 : 0;
sum += mineField[i+1][j].getIsMine() ? 1 : 0;
sum += mineField[i+1][j+1].getIsMine() ? 1 : 0;
mineField[i][j].setAdjacentMines(sum);
This is count up how many are mines and use it properly. It may be more clean to create a loop to perform this calculation, since it is the same thing for each adjacent field.
Try something like:
private static int countAdjacentMines(int x, int y) {
int adjacentMines = 0;
for(int i = -1; i <= 1; i++) {
if((x + i < 0) || (x + i >= width)) {
continue;
}
for(int j = -1; j <= 1; j++) {
if((y + j < 0) || (y + j >= height)) {
continue;
}
if(mineField[x + i][y + j].getIsMine()) {
adjacentMines++;
}
}
}
return adjacentMines;
}
This should count the number of mines neighbouring a block at (x, y).

Categories

Resources