Java function not working when called twice - java

public static int getMinor(int[][] mat, int r, int c) {
int minor = 0;
int[] min = new int[4];
int x = 0;
while (x <= 3) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i != r && j != c && mat[i][j] != 100) {
min[x] = mat[i][j];
x += 1;
mat[i][j] = 100;
}
}
}
}
minor = min[0] * min[3] - min[1] * min[2];
return minor;
}
public static void main(String[] args) {
int[][] mat = getMatrix();
System.out.println(getMinor(mat, 0, 0));
System.out.println(getMinor(mat, 1, 1));
}
for some reason when I call getMinor function again the code stops working.
It prints the minor the first time but does not work when I call it again in the next line.
getMatrix function just gets the matrix.

Your code contains the potential for an infinite loop. It is possible for (x <= 3) to never become false, and so for your while loop to run forever. You haven't given your input matrix, but I assume that what is happening is that the first call to getMinor returns and so println prints the returned result, but then the execution goes into getMinor the second time and gets stuck...never comes out, and so the second println never occurs and the program never exits.
Yes, that's what's going on. I just made up an arbitrary matrix, and my run prints a 0 and then locks up in the second call to getMinor, going around and around in the while loop forever with if (i != r && j != c && mat[i][j] != 100) never being true, and so x never changing. This occurs because you're operating on the same matrix the second time, and the locations already set to 100 are sufficient to cause the while loop to never exit.
If you start with a fresh matrix the second time, this doesn't so easily occur. This code, at least with my sample matrix, completes:
int[][] mat = getMatrix();
System.out.println(getMinor(mat, 0, 0));
mat = getMatrix();
System.out.println(getMinor(mat, 1, 1));
Another potential problem with your code (I say potential because maybe you will never use the wrong parameters so that this happens) is if you pass in r and c values that are larger than the w/h bounds of the matrix, then the program crashes with an index out of bounds error because the if clause succeeds more than 4 times in a run through the matrix, and so you haven't allocated enough slots in the min array, and min[x] = mat[i][j]; goes bang!.

You've changed the value of "mat" in "getMinor", so 2ed call dose not have same input as the 1st one . (You may read this to figure out java's "pass by reference" VS "pass by value")
It's not a good practice to modify input within a function named as "getXXX"

Related

Skipping To The Next if Statement from Inside a for Loop

I've been learning some Java in my spare time and I'm a beginner, so I'm very sorry if I don't understand some simple concepts. I've been trying to make a "Robot" move around an already made map. I've been trying to make lines of a text file into multiple arrays (ie. moving forward, turning left, turning right). Then, I've been trying to use values in those arrays to make the robot move. Basically, if the text file says:
1 0 0
0 1 0
0 0 1
So the first line is for moving, the second is for turning left and the third is for turning left. This is supposed to make the robot move, and then not turn. Then it moves on to the next column and doesn't move, turns left, and doesn't turn right. I'm trying to make sure it works no matter how long the code is. I'm able to put it into three arrays correctly, but I'm having trouble with this for loop. When the loop executes and the values are all 1's or above, it works perfectly. However, if any value is a 0, it completely exits the loop and the robot doesn't move. Any help or advice would be appreciated! Thank you!
Code is below:
public static void robotMove(Robot x) throws Exception {
for (int i = 0; i < movedata.length; i++) {
int y = movedata[i];
int s = leftdata[i];
int j = rightdata[i];
for (int a = 0; a < movedata.length; a++) {
if (y == 0) {
//asking what to put here
}
else {
again.Move(x, y);
}
if (s == 0) {
//asking what to put here
}
else {
again.Left(x, s);
}
if (j == 0) {
//asking what to put here
}
else {
again.Right(x, j);
}
}
}
Assuming that movedata, leftdata and rightdata are the 3 arrays of same size corresponding to each line of your example, without knowing what again is but assuming it is the object handling the .Move(), .Left() and Right() actions made on the Robot x, I think the following should be enough:
public static void robotMove(Robot x) throws Exception {
for (int i = 0; i < movedata.length; i++) {
if (y != 0) {
again.Move(x, movedata[i]);
}
if (s != 0) {
again.Left(x, leftdata[i]);
}
if (j != 0) {
again.Right(x, rightdata[i]);
}
}
}
You can loop just once through movedata, I've removed the second nested loop.
If the value is 0, you do not want to do anything. Hence you don't need an else part for that, just put code in the if value != 0.
From a code perspesctive, it would be cleaner if instead of having some if taking care that the value is not 0, you may implement the "inaction" directly in the methods .Move(), .Left() and .Right().

putting a formula into a for loop

I'm trying to put this formula into a loop
The function to put inside the loop
I've used if statements to give me a specific result if the input is zero, but if the input is one or higher, the for loop should run.
I was given a question regards recursion and supposed to execute it 3 different ways one of them using a loop that I've already made and runs but gives unexpected results.
public class Assignment5Recursion {
public static int puzzleLoop(int n) {
int v=0;
if(n>=1) {
for(int i=1; i<=n+1; i++) {
v = (2*i-1);
}
return ((2*n+1)+2*v);
}
else {
return 1;
}}}
if n is 1, the result should be 5, if n is 2, the result should be 13, if n is 3, the result should be 25, if n is 7, the result should be 113, but for some reason, I'm getting different outputs, so I'm assuming that I've set the loop wrong.
You need to make 2 changes.
1)The loop will run from i=1 to i=n+1 whereas you only require it to run till i=n.
So the for loop exit condition should either be i<n+1 or i<=n
2)The variable v is going to be replaced every run of the loop as it is getting assigned a new value every time.
So the value for v will always be v=2*(n+1)-1 according to your code.
You need to make this v += (2*i-1) so that the new value of v gets added to the old value to get sigma(sum).
Replacing your for loop as below will solve your problem.
for(int i=1; i<n+1; i++) {
v += (2*i-1);
}
or
for(int i=1; i<=n; i++) {
v = v+(2*i-1);
}
You have made two mistake, instead of adding to v you are updating on every iteration, so total values doesn't get summed up. And since you are using <= you don't need to iterate upto n+1. So here is a revised puzzleLoop method for you
public static int puzzleLoop(int n) {
int v = 0;
if (n >= 1) {
for (int i = 1; i <= n; i++) {
v += (2 * i - 1);
}
return ((2 * n + 1) + 2 * v);
}
return 1;
}
You also don't need the else part statement since if it is not in the if block you can always safely return 1.
Σ(2*i-1), sum should be carried over the loop
change the statement in loop to v = v+(2*i-1) and condition to i<=n

break resulting in an infinite for loop?

I'm making a project for an online course. I don't want the computer-generated coordinates(xOfCompShips, yOfCompShips) to repeat themselves or be the same as those inputted by the user(xOfPlayerShips, yOfPlayerShips). So in case, the same coordinates are generated the if statement would decrease the value of i and make the loop run once more, replacing the duplicated coordinates. By printing lines for debugging I found out that the break statement seems to break the for loop with k and the control goes back to the for loop with i and without any new values being assigned to xOfCompShips,yOfCompShips(or perhaps same values being reassigned to them), the control goes back to the for loop with k and again back to the for loop with i and it keeps going back and forth.
I tried removing the break statement but then if the first random coordinates are a duplicate pair, the array is accessed for index = -1.
for(int i = 0; i < xOfCompShips.length; i++) {
xOfCompShips[i] = (int)Math.floor(Math.random() * 10);
yOfCompShips[i] = (int)Math.floor(Math.random() * 10);
for(int k = 0; k < xOfPlayersShips.length; k++) {
if((xOfCompShips[i] == xOfCompShips[k] && yOfCompShips[i] == yOfCompShips[k])
|| (xOfCompShips[i] == xOfPlayersShips[k] && yOfCompShips[i] == yOfPlayersShips[k])){
i--;
break;
}
}
}
I expect new random values are to be assigned to xOfCompShips and yOfCompShips each the if statement is executed.
(int) Math.floor(Math.random() * C) is the wrong way to do it, this doesn't get you quite uniform output, and it's also needlessly complicated. Make an instance of java.util.Random (and don't keep recreating it; make one instance once, and reuse it), and call rnd.nextInt(10) on that.
you loop k from 0 to xOfPlayersShips, and then use k as index to xOfCompShips. I doubt that's right.
as part of your loop, you say: if (xOfCompShips[i] == xOfCompShips[k] && yOfCompShips[i] == yOfCompShips[k]) restart loop. if i and k are the same, obviously that is true. i starts at 0, k starts at 0.. 0 == 0.
A run with a debugger would have shown you this rather quickly.
Have you tried also breaking out of the outer loop (i.e. k--;), if I understand correctly (which I don't think I do), you're changing i over and over but k is always the same triggering the loop to change i more.
for(int i = 0; i < xOfCompShips.length; i++) {
xOfCompShips[i] = (int)Math.floor(Math.random() * 10);
yOfCompShips[i] = (int)Math.floor(Math.random() * 10);
for(int k = 0; k < xOfPlayersShips.length; k++) {
if((xOfCompShips[i] == xOfCompShips[k] && yOfCompShips[i] == yOfCompShips[k]) ||
(xOfCompShips[i] == xOfPlayersShips[k] && yOfCompShips[i] == yOfPlayersShips[k])){
i--;
**k--;**
break;
}
}
}

How to get code to double values (x * 2) less than 10 in an array? (Java)

I'm taking an online Java programming class (I'm a beginner) and I cannot figure how to correctly complete the code. I've already written what I think is to be included, however I'm missing something that would make the code work completely.
Directions:
Double any element's value that is less than minVal. Ex: If minVal = 10, then dataPoints = {2, 12, 9, 20} becomes {4, 12, 18, 20}.
public class StudentScores {
public static void main (String [] args) {
final int NUM_POINTS = 4;
int[] dataPoints = new int[NUM_POINTS];
int minVal = 0;
int i = 0;
dataPoints[0] = 2;
dataPoints[1] = 12;
dataPoints[2] = 9;
dataPoints[3] = 20;
minVal = 10;
// DO NOT EDIT ANYTHING ABOVE THIS COMMENT. ABOVE IS THE DEFAULT CODE OF ASSIGNMENT
for (i = 0; dataPoints[i] < minVal; ++i) {
dataPoints[i] = dataPoints[i] * 2;
}
// DO NOT EDIT ANYTHING BELOW THIS COMMENT. BELOW IS DEFAULT CODE OF ASSIGNMENT
for (i = 0; i < NUM_POINTS; ++i) {
System.out.print(dataPoints[i] + " ");
}
System.out.println();
return;
}
}
I made comments of what isn't to be messed with, as I am using an online interactive book and cannot edit or change the default code. Additionally, we are working with arrays in this chapter.
I'm new to this site in the sense that I don't know the unwritten ways of stackoverflow, but I've search multiple times online to see how to double the values for an array in java but I do not get the search results I need to help me.
The error messages I get are:
Testing minVal = 10 and dataPoints = {2, 12, 9, 20}
Expected output: 4 12 18 20
Your output: 4 12 9 20
I thought that the compiler should be able to read the lines fully to register that 9 is also less than 10 and thus should be doubled to 18, but it doesn't. What am I missing to make 9 be read as well?
In your code, 12 < 10 evaluates to be false and so, it goes out of loop and hence, it gives Wrong Output. Check the below code:
for (i = 0; dataPoints[i] < NUM_POINTS ; ++i) {
if(dataPoints[i] < minVal) {
dataPoints[i] = dataPoints[i] * 2;
}
}
I looped through all elements of array and if an element is < minVal, I multiplied it by 2.
The second section of the for statement is the termination condition: once it evaluates to false, your loop will stop executing.
In this particular problem, you're trying to look at each value in your dataPoints array, and double it. This calls for the use of an index variable.
Your index variable will keep track of your position within the array as you move from left to right. Starting on the left, at index 0, you will move right until you're at the end of the array.
++i takes care of incrementing your index variable each time the loop runs. This is what moves you through the array.
Your termination condition should check whether you have looked at all values in the array. Once you've gone past all the values in your array your index variable is pointing all the way at the end. And remember, as soon as the termination condition is false your loop will stop executing. So you want to run your code while i (your index variable) is less than the size of the array (dataPoints.length).
Once you've figured out the for loop bounds, simply check your conditional with an if-then statement before updating the values:
for (i = 0; i < dataPoints.length; ++i) {
if (dataPoints[i] < minVal) {
dataPoints[i] = dataPoints[i] * 2;
}
}
for (i = 0; i < NUM_POINTS; ++i) {
if (dataPoints[i] < minVal) {
dataPoints[i] = (dataPoints[i] * 2);
}
}

The code after my for loop doesn't execute

I have a short program that creates an array of integers and removes non-primes:
public class Main {
public static void main(String[] args){
int[] nums = new int[100];
for (int i = 0; i < nums.length; ++i){
nums[i] = i + 1;
}
int j = 0;
while(j < nums.length){
System.out.print(nums[j]);
System.out.print(" ");
j++;
}
for (int n = 1; n < nums.length / 10; n++){
for (int p = n; p < nums.length; p += nums[n]){
if(p > n){
nums[p] = 0;
System.out.println("p"+nums[p]);
}
}
}
//this code doesn't execute
System.out.println("x");
}
}
The statement which is supposed to simply print "x" doesn't execute, nor does any other statement I put after the for loop. The program does not enter an infinite loop, so what's going on? I feel like this is something obvious that I'm just missing.
Edit: it was an infinite loop, I just didn't realize it.
In your p loop, on the second iteration, p > n is true and you set nums[p] to 0. From that point forward, p will never increase, because your incrementer is p += nums[n] and nums[n] is 0, and so your loop never terminates.
This sort of problem is best solved by using a debugger. Using a debugger is a fundamental skill for a programmer. With a debugger, you can step through statements, inspect variables, and see exactly what your code is doing. It's not an advanced technique, it's essential from Day 1 so you can correctly diagnose issues with your code. If you don't currently know how to use a debugger, stop what you're doing and learn to use one, it will be incredibly valuable and time-saving to you. There's almost certainly one built into your IDE.
Are you falling into a infinite loop? In the console press cmd+c or ctrl+c and see what that does. If the program stops it is a sign of a infinite loop.

Categories