Having an issue printing the results of i when I'm incrementing DOWN starting from startVal and ending at endVal with an increment of incVal.
the first if statement is printing correctly and I had THOUGHT that the second else if statement should be fairly similar however even though my original values; for EX: if startVal = 100, endVal = 10, and incVal = -1, it jumps to the else if statement correctly (tested with a basic print statement) but the for loop doesn't seem to work and not print out the results of i like it should.
if ((startVal < endVal) && (incVal >= 1))
{
for (int i = startVal; i <= endVal; i += incVal)
{
System.out.println(i);
}
}
// else if incrimenting down
else if((startVal > endVal) && (incVal <= -1))
{
for (int i = startVal; i <= endVal; i -= incVal)
{
System.out.println(i);
}
}
Is there something stupid I'm messing up here? I've tried different things inside the for loops to get i to print but it doesn't work the correct way..
It's because you didn't change the for loop in the else clause
for (int i = startVal; i >= endVal; i += incVal)
{
System.out.println(i);
}
edit: incValue should also be increasing since you have i=-1, thanks mstbaum
Your problem is that if (startVal > endVal) is true, your first iteration of your for loop will be be false because int i = startVal; i <= endVal, which evaluates in the first iteration as startVal <= endval.
You are also decrementing by a negative number (guaranteed by your incVal <= -1 condition), which will result in i actually because of i -= incVal.
Related
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;
}
}
}
I was not able to find the answer to this question. I was working on an insertion sort method and it wouldn't properly execute:
public static <T extends Comparable<? super T>> void insertionSort(T[] array) {
int length = array.length;
T temp;
for (int i = 1; i < length; i++) { //start of unsorted
temp = array[i]; //save the element
int j = i-1;
while (temp.compareTo(array[j]) < 0 && j >= 0) { // while temp is less than array[j]
array[j+1] = array[j];
j--;
} //end of while
array[j+1] = temp; //as soon as temp is greater than array[j], set array[j] equal to temp
}
}
This returned an ArrayIndexOutOfBoundsException on the while loop line, but when I switched the conditions in the while loop around to this:
while (j >= 0 && temp.compareTo(array[j]) < 0)
it worked. I didn't think in Java the order of conditions in a while loop mattered to the program? This is very strange to me, as I've never seen or heard of order mattering in a statement with && since I assumed that the two while loop lines were equivalent. I was stuck wondering this for a while and couldn't find an answer.
Can someone explain why this is so?
Conditions are evaluated left to right.
Initially, for case j=-1, your code wasn't evaluating the second condition because the first one was throwing an ArrayIndexOutOfBoundsException exception.
while (temp.compareTo(array[j]) < 0 && j >= 0)
However when you switched the conditions like this:
while (j >= 0 && temp.compareTo(array[j]) < 0)
then for the same case (j=-1), since first condition becomes false, then regardless of the second value, the whole condition will always be false; and so the second condition won't be evaluated and hence no exception in this case.
Lets consider the following example:
boolean b = Condition_1 && Condition_2;
Now if the Condition_1 is always false then whatever the value of Condition_2, b will always be false. So when first condition is false of an 'and' then no need to check the value of second condition that is what exactly happened here.
It's exactly error if you use the condition while (temp.compareTo(array[j]) < 0 && j >= 0)
In Java, it checks condition && first and then checks || after.
In the condition && it checks in the order.
Therefore, in your case while (temp.compareTo(array[j]) < 0 && j >= 0), it check this condition temp.compareTo(array[j]) firstly. If j out of the array index, ==> you get error
When you change the condition to while (j >= 0 && temp.compareTo(array[j]) < 0), it check j>=0 firstly, if j = -1 the program cannot go further.
How to manipulate the for loop, the question is on the comments
How to re-enter the for loop and adding the index dynamically except for the auto increment.
for (int i = 0; i < words.size(); i++)
{
try {
temp = QueryWithContext.query(words.get(i));
if((temp == null || temp.isEmpty()) && words.size() > i+1)
{
QueryWithContext.query(words.get(i)+" "+words.get(i+1));
temp = QueryWithContext.query(words.get(i)+" "+words.get(i+1));
System.out.println("1st if");
//if condition = true, the codes below must not run anymore
//and for loop will increment by 1 except for the auto inc
if((temp == null || temp.isEmpty()) && words.size() > i+2)
{
System.out.println("2nd if");
temp = QueryWithContext.query(words.get(i)+" "+
words.get(i+1)+" "+words.get(i+2));
//if condition = for loop will increment by 2
//except for the auto inc
}
}
}
}
If you meant increasing the loop index, then you can increase the i value that represents the index. i += 2; should do the work. It will eventually increase it by 3 when the loop ends and starts over.
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.
A little background, I saw a question on here a while back about creating a program that asks how many people are in the room, and then you 'interview' each person on their age, assign them to an age group, and then print their age group and the amount of people in that age group. I decided to take a shot at it off of needing an idea for a practice program, unfortunately the code terminates before getting the first for statement and i'm not exactly sure why. I assume it would be a syntax error but I honestly have no idea, so any help is greatly appreciated.
import java.util.Scanner;
public class UnkownProjects {
public static void main(String[] args){
Scanner stringInput = new Scanner(System.in);
Scanner numInput = new Scanner(System.in);
System.out.println("How many people are in the room?");
int amountOfPeople = numInput.nextInt();
int[] totalPeople = new int[amountOfPeople];
System.out.println("Test");
for(int index = 0; index == totalPeople.length; index++){
System.out.println("Please enter an age for each person in the room:");
int ageOfPerson = numInput.nextInt();
ageOfPerson = totalPeople[index];
System.out.println("Test");
}
for(int index = 0; index == totalPeople.length; index++){
if(totalPeople[index] < 20 && totalPeople[index] > 0){
int[] underTwenty = null;
underTwenty[index] = totalPeople[index];
System.out.println("Test");
}
}
}
}
I also know the spacing is a bit off but I just copy/pasted and tried to make it look pretty for you all, so don't worry. Oh and the 'println' statements were just there to check and see where the program terminates.
Output:
How many people are in the room?
(A number you would've entered here)
Test
Ninja Edit:
Decided that I should come back to this post and place the finished code here for anyone who comes across this question and would like to take a look at the finished product.
import java.util.InputMismatchException;
import java.util.Scanner;
public class InterviewClass {
public static void main(String[] args){
try{
Scanner numInput = new Scanner(System.in);
System.out.println("How many people are in the room? (Ex: 5, 10, 24)");
int totalPeopleInRoom = numInput.nextInt();
int[] agesOfPeopleInRoom = new int[totalPeopleInRoom];
int youngPeople = 0, middleAged = 0, oldPeople = 0, deadPeople = 0;
System.out.println("Please enter an age for " + totalPeopleInRoom + " people (Ex: 17, 21, 45):");
for(int index = 0; index < agesOfPeopleInRoom.length; index++){
int tempAgePlaceHolder = numInput.nextInt();
agesOfPeopleInRoom[index] = tempAgePlaceHolder;
if((index + 1) == (totalPeopleInRoom/2)){
System.out.println("Half way there!");
}
}
System.out.println("Age Group\tAmount In Group");
for(int index = 0; index < agesOfPeopleInRoom.length; index++){
if(agesOfPeopleInRoom[index] < 30 && agesOfPeopleInRoom[index] > 0){
youngPeople = youngPeople + 1;
}
if(agesOfPeopleInRoom[index] < 60 && agesOfPeopleInRoom[index] > 30){
middleAged = middleAged + 1;
}
if(agesOfPeopleInRoom[index] < 115 && agesOfPeopleInRoom[index] > 60){
oldPeople = oldPeople + 1;
}
else if(agesOfPeopleInRoom[index] < 0 || agesOfPeopleInRoom[index] > 115){
deadPeople = deadPeople + 1;
}
}
System.out.println("Young People:\t" + youngPeople);
System.out.println("Middle Aged:\t" + middleAged);
System.out.println("Old People:\t" + oldPeople);
System.out.println("Dead People:\t" + deadPeople);
System.out.print("Total People:\t");
System.err.println(totalPeopleInRoom);
}catch(InputMismatchException inputException){
System.err.println("[ERROR] Wrong type of input used: " + inputException);
}
}
}
This is a bad for loop: for(int index = 0; index == totalPeople.length; index++)
Instead do: for(int index = 0; index < totalPeople.length; index++)
Let's break the for loop down:
The first part of the loop, int index = 0 is the initial condition. It tells the loop what the index should be set to when the loop starts.
The 2nd item in the for loop, in your loop you have index == totalPeople.length, is the condition statement that tells the for loop whether to keep looping if true or to stop looping if false. Your statement will be false when the loop tries to begin, and so the loop will never begin. So this is where your problem is. Instead you want to tell it to continue looping as long as the index is less than the length of the array, or in Java, index < totalPeople.length.
The 3rd item in the loop, here index++, tells the loop what to do with the index at the completion of each loop. Here you're telling it to increase by one, which is good.
The for loop condition must be true for it to iterate; it breaks out when it's false. In your case, it's false right away, so it never executes.
Instead of
for(int index = 0; index == totalPeople.length; index++){
try
for(int index = 0; index < totalPeople.length; index++){
And similarly for the other for loop.
In the Java tutorial on for loops, it states this:
When the termination expression evaluates to false, the loop terminates.
for(int index = 0; index == totalPeople.length; index++){
The second part in the parentheses is not a stopping condition, it is a check to continue. Use:
for(int index = 0; index < totalPeople.length; index++){
for(int index = 0; index == totalPeople.length; index++) should be
for(int index = 0; index < totalPeople.length; index++)
otherwise the boolean condition is evaluated to false and hence the loop doesn't execute
You should read this.
The general form of the for statement can be expressed as follows:
for (initialization; termination;
increment) {
statement(s) }
When using this version of the for statement, keep in mind that:
1. The initialization expression initializes the loop; it's executed once, as the loop begins.
2. When the termination expression evaluates to false, the loop terminates.
3. The increment expression is invoked after each iteration through the loop; it is perfectly acceptable for this expression to increment
or decrement a value.
Your for loops are saying
Continue doing this code while index is equal to the arrays length
What you mean to say is continue doing this code while index is less than the arrays length