Retrying a for loop? - java

Is it possible to use a for lop to set a condition of an object. And if that condition does not pass a test (if statement), the condition is changed until it does pass the test? Here is my pseudo code attempt, but i doubt it will work:
for (int i = 0; i < myArray.size(); ++i){
myArray.get(i).position = random Position
if(myArray.get(i).position == allowed position){
//Success!
}else{
//re-attempt to change position until it meets criteria
}
}
Please dont hate, i just started Java. And english is not my native language
Thank you

You could use a while loop:
myArray.get(i).position = random Position
while (myArray.get(i).position != 100) {
myArray.get(i).position = random Position
}
// Success!

Just Modify your Code Little.
for (int i = 0; i < myArray.size(); ++i){
myArray.get(i).position = random Position
if(myArray.get(i).position == allowed position){
break;
//Success!
}else{
//re-attempt to change position until it meets criteria
// countinue
}
}
by writing break, your loop is terminated when you get your desired value.

boolean correctPosition=false;
for (int i = 0; !correctPosition; ++i){
myArray.get(i).position = random Position
if(myArray.get(i).position == 100){
correctPosition=true;
//Success!
}else{
//re-attempt to change position until it meets criteria
}
}

Related

comparing elements in an array and fetching new ones

I realize this has been asked before and I had a look at it but, for me, it only works to a point. After some struggle, I thought I'd ask.
I have an array of floats in an object's constructor.
That goes like this:
count = 3;
angles = new float[count];
The array length is really small though I'd like implement a modular and reusable approach.
I loop through the array assigning floats:
for (int i = 0; i < angles.length; i++) {
angles[i] = radians(random(360));
}
Then, with a new loop, I check if the singular elements have less than 30 degrees in between them, and if so, assign a new random value:
for (int i = 0; i < angles.length; i++) {
for (int k = i+1; k < angles.length; k++){
if(angles[i] != angles[k]){
if(abs(angles[i] - angles[k]) <= radians(30)){
angles[i] = radians(random(360));
}
}
}
}
This works nice and well but it doesn't guarantee that the new random number will keep the 30 degrees limit with the remaining elements. This, I assume, has to do with the length of the 'for' loop.
What would be the best way to overcome this and guarantee that newly fetched number will always conform to the 30 degree rule?
Instead of just checking once with an if statement, you could change it to a while statement, so that it attempts to find a new random number until the new one works.
while (abs(angles[i] - angles[k]) <= radians(30)){
angles[i] = radians(random(360));
}
However, if there are no numbers that follow your 30 degree rule, your program will get stuck in this loop, so you might want to check that there is a possible solution before entering the loop.
Edit: the above solution will ensure that the number follows the 30 degree rule with only one number in your array. Add a boolean to determine if the condition has been met, and loop until the boolean is true.
for (int i = 0; i < angles.length; i++) {
boolean meetsCondition = false;
while (!meetsCondition) {
for (int k = 0; k < angles.length; k++){
if(i != k){
if(abs(angles[i] - angles[k]) <= radians(30)){
angles[i] = radians(random(360));
meetsCondition = false;
break;
}
}
}
meetsCondition = true; //if the for loop completes, it has met the condition.
}
}
Why not use recursion earlier on:
for (int i = 0; i < angles.length; i++) {
angles[i] = findSuitable( i==0 ? 0 : angles[i-1] )
}
...
float findSuitable(float limit){
float sample = radians(random(360));
if(Math.abs(sample-limit) > 30)
return sample;
else
return findSuitable(limit);
}
In my opinion, you can try to change the the codes of random to this:
Random d = new Random();
int a = d.nextInt(360);

While-loop Restriction

I want to restrict the while Loop.
I don't want to use break;, instead I want to say that the loop must end after three times.
My while Loop:
while(!file.isFile()) { userInput = JOptionPane.showInputDialog("UserInput);
int i = 0;
while(!file.isFile() && i < 3) {
userInput = JOptionPane.showInputDialog("UserInput);
i++;
}
And I agree that for loop is better choice :)
Use a for loop instead :
for (int i = 0; i < 3 && !file.isFile(); i++) {
userInput = JOptionPane.showInputDialog("UserInput");
...
}
Consider refactoring to a for loop, introducing a counter variable in a tight scope:
for (int i = 0; i < 3 && !file.isFile(), ++i){
userInput = JOptionPane.showInputDialog("UserInput"/*ToDo - quotation inserted*/);
}
The for loop conditional check i < 3 && !file.isFile() is verified before the statement in the loop body is ran.
Then you need to make your while loop a for-loop like thing:
int counter = 0;
while (counter < 3 && !file.isFile()) { ...
counter++;
For the record: the code you are showing isn't really useful: you are "overriding" the input you get from the user; and: you are condition !file.isFile() ... will not change its value ... because there is no code that would do that. In other words: there is more to fix about your code than just the way you are looping. It simply seems weird to ask the user the same thing three times; to ignore what he says the first two times.
int i = 3;
while(!file.isFile() && i>0) {
userInput = JOptionPane.showInputDialog("UserInput");
i--;
}
int counter = 0;
while(!file.isFile() && counter < 3) {
userInput = JOptionPane.showInputDialog("UserInput);
counter++;
}
Replace 3 with the number of iterations you would like the loop to be limited to.
int count = 0;
while(!file.isFile() && count < 3 ) {
count++;
}

How to break out of nested loops

I'm currently making a program where nested loops are needed to search through an array to find a spot for good input within the array. Here is an example:
public void placePiece(int column) {
boolean goodInput = false;
while(!goodInput) {
for(int x = 5; x >= 0; x--) {
if(boardStatus[x][column] == 0) {
setRow(x);
boardStatus[x][column] = 1;
goodInput = true;
break;
}else if(boardStatus[0][column] == 1) {
goodInput = false;
break;
}else{
}
}
}
}
The method takes a parameter which is the column in which the piece should be located (received by a mouse listener). If the column in the 2D array is already filled to the top, the program gets stuck in an endless loop within the "else if", and I'm unsure how I would break out of this loop. How could I break out of this loop if there is bad input so that the user can try to give another column as input.
An easy way is to use a labeled break statement.
myLabelName:
for(outer loop)
for(inner loop)
if(condition)
break myLabelName;
This is useful when you'd rather not waste time iterating over other objects/items when you've found what you needed.
To expand, when you use just break; (without a label) it will exit the parent loop.
Ex:
myLabelName:
for(outer loop){
for(inner loop){
if(condition){
break myLabelName; //breaks outer loop
}
else if(other condition){
break; //breaks parent (inner/nested) loop
}
}
}
When you are in elseif loop your are again assigning the goodInput = false; so the while conditions again becomes true and loops continuous forever.
if you want to take input till correct input is received can use do(){}while() loop
Based on the description you provided, I am not sure of the purpose of the else if statement. As I understand you intention, you are checking all of the rows within a certain column to see if that cell has been set or not?
The combination of the while loop and the for loop seems suspect as well. There doesn't seem to be any need for the while loop in this case.
What is supposed to happen if the entire column is filled? Should this method return a status flag?
Can't this be implemented with a single for loop?
for (int x = 5; x >= 0; --x)
{
if(boardStatus[x][column] == 0) {
setRow(x);
boardStatus[x][column] = 1;
break;
}
}
If you want, you can track a flag variable to indicate if you ever found a cell which was empty.
you can use flag or you can use goto statement
flag description
code
bool flag = true;
for (int i = 0; (i < 10) && (flag==true); i++)
{
for(int j = 0; (j < 10) && (flag==true); j++)
{
if (condition)
flag = false;
}
}
Change the parameter AFTER the loop:
public void placePiece(int column) {
boolean goodInput = false;
while(!goodInput) {
for(int x = 5; x >= 0; x--) {
if(boardStatus[x][column] == 0) {
setRow(x);
boardStatus[x][column] = 1;
goodInput = true;
break;
}else if(boardStatus[0][column] == 1) {
goodInput = false;
break;
}else{
}
}
goodInput = true; // <-----
}
}

increament the value of arraylist element by one java

I have one dimensional array list and I need to add one to the arraylist element each step if a certain condition was satisfied this is equavelent for example to number[i]=+1; I am applying the following loop
For(int i=0;i<Number;i++)
{if certain condition was met then
Array_list_element.get(i)=Array_list_element.get(i)+1;
else perform another action}
but how I can do this Array_list_element.get(i)=Array_list_element.get(i)+1;
I am a little confused if I did the following code
Array_list_element.get(i).add(1)
will the value of Array_list_element.get(i) will be always one or the one will be added at each step the condition is satified how you suggest to do this
Thanks in advance
The following code will increment the value of each element.
for (int i = 0; i < arrayList.size(); i ++) {
int oldVal = arrayList.get(i);
int newVal = oldVal + 1;
arrayList.set(i, newVal);
}
You just need to now put your conditional check either around the for loop if you want every element to increase. Or if you want specific elements to increase then you need to possibly perform a check on the oldVal if that is what you are basing it on.
Edit: So looks like you want the check inside the for loop so here is an example.
for (int i = 0; i < arrayList.size(); i ++) {
int oldVal = arrayList.get(i);
if (oldVal == 2) {
int newVal = oldVal + 1;
arrayList.set(i, newVal);
} else {
continue;
}
}

What is wrong with this method using an int[][]?

This method is supposed to return true if there is more than one 1 in a column of a 2D array, yet it doesn't work. I can't figure out what's wrong with it so I thought I'd get some expert opinions.
Example:
10010
01001
10100
will return true because there are 2 ones in the first column.
Here is the code
public static boolean isVert(int[][] x) { //checks for more than one 1 in columns
int count = 0;
boolean break2 = false;
boolean check = false; //false means no 2 (or more) queens in same column
for (int i = 0; i < x.length; i++) {
count = 0;
for (int j = 0; j < x[i].length; j++) {
if (x[i][j] == 1) {
count++;
}
if (count > 1) {
break2 = true;
check = true;
break;
}
}
if (break2) {
break;
}
}
return check;
}
You break at the first occurance of 1 in whole array, which is probably not the expected result.
Explanation of how your code works:
loop until counter i is less than length of array (number of rows in array)
loop until counter j is less than length of i-th row (number of columns or elements in array)
check if element on i-th row and j-th column is 1, if true, increase variable count by one
if count is greater than 1 (this means it has to be 2 or greater) set break2 and check to true, break
if break2 is true (which is as count is > 2 and first loop breaks), break this loop too:
this happens in 1st row of your example table
end of loops, return check (which is true because 1st row contains 2 ones)
The problem in your code is that you break when you find your first row that satisfies your condition, but you do not (necessarily) check all the rows in given array.
I have corrected the code for you, hopefully it works (untested)
public static boolean isVert(int[][] x) { //checks for more than one 1 in columns
int count = 0;
for (int i = 0; i < x.length; i++) {
int rowCount = 0;
for (int j = 0; j < x[i].length; j++) {
if (x[i][j] == 1) {
rowCount++;
}
if(rowCount > 1) {
count++;
break;
}
}
}
// returns true if count of lines containing 1 equals length of array,
// if not, returns false
return count == x.length;
}
Start of by improving your naming convention. Your code has many variables named by their contents, instead of named by how they are used. For example:
boolean check = false; // false means no two queens in the same column.
instead of
boolean twoQueensInColumn = false;
and the other example
boolean break2 = false;
instead of the more reasonable
boolean continueLooking = true;
Plus, it is a very good idea to avoid using variables as place holders for loop escaping logic. For example, the two stanzas
...
if (count > 1) {
break2 = true;
check = true;
break;
}
}
if (break2) {
break;
}
are a breeding ground for bugs, requiring a lot of debugging to ensure they work "right now" which will break just as soon as you modify the code. Much better would be
boolean keepLooking = false;
for (int row = 0; keepLooking && (row < board.length); row++) {
int queensInColumn = 0;
for (int column = 0; keepLooking && (column < board[row].length, column++) {
if (board[row][column] != 0) {
queensInColumn++;
}
if (queensInColumn > 1) {
keepLooking = false;
}
}
}
The main difference being the control logic is in the loop "conditional" block, where it belongs.
I would recommend turning your integers to string and using the .contains() method and looping through that. This would make the code easier to understand.

Categories