Java: Incrementing a variable inside of a for loop - java

I am in a beginner Java class and for a project I need to count how many times a condition returns TRUE(correctGuess) or FALSE(incorrectGuess) with a loop inside of a loop. The problem that I'm having is that the variables being incremented within the inner loop do not hold their incremented value as the loop reiterates. Therefore, the outer while-loop's condition is never false. I'm really new to programming and I can't figure out the solution. Thank you in advance for your time with this silly question and if there are any questions I would be happy do a better explanation. The code looks like this:
int incorrectGuess = 0;
int correctGuess = 0;
while(incorrectGuess < 6 && correctGuess < WORD_LENGTH) {
//Gets the users first guess
System.out.print("Please guess a letter [A-Z]: ");
letterGuessed = keyboard.nextLine();
for (int i = 0; i < WORD_LENGTH; i++){
char value = wordLetterArray[i];
String letterArray_value = String.valueOf(value);
if(letterGuessed.equals(letterArray_value)){
++correctGuess;
}
else
System.out.println("Bad comparison!");
if(i == WORD_LENGTH)
++incorrectGuess;
}
}

Looks like you may need to redesign the whole algorithm, but I can tell you what your main issue is with this looping forever:
// Seems legit
while(incorrectGuess < 6 && correctGuess < WORD_LENGTH) {
// Still seems legit
for (int i = 0; i < WORD_LENGTH; i++)
// Well, there's a problem, i will never be equal to word length
//because a condition of the for loop is i < WORD_LENGTH
if(i == WORD_LENGTH)
++incorrectGuess;
Again, I feel you need to redesign your whole algorithm, but if you want it to continue, just pull the incorrectGuess increment line out of the for loop. This will give you the intended result:
for (int i = 0; i < WORD_LENGTH; i++){
char value = wordLetterArray[i];
String letterArray_value = String.valueOf(value);
if(letterGuessed.equals(letterArray_value)){
++correctGuess;
}
else {
System.out.println("Bad comparison!");
}
}
incorrectGuess++;

Related

How to find first instance of element array

I'm a pretty basic programmer and I'm coding a 'Master-mind' style guessing game program.
Now the part I'm stuck with is that I want to go through an array and increase the pointer when I come across a specific number.
Now thats pretty easy and stuff, but what I want to do is ONLY increase the counter if the number is encountered for the first time. So, for example if there are two numbers (189, 999), I want the counter to increase only once, instead of 3 times, which is what my code is doing. I know why its doing that, but I can't really figure out a way to NOT do it (except maybe declaring an array and putting all the repeated numbers in there and only incrementing it if none of the numbers match, but that's super inefficient) Here's my code:
for (int i = 0; i < mString.length(); i++) {
for (int j = 0; j < nString.length(); j++) {
if (mString.charAt(i) == nString.charAt(j)) {
correctNumbers++;
}
}
}
Thanks for taking the time to read! I'd prefer it if you wouldn't give me a direct answer and just point me in the right direction so I can learn better. Thanks again!
Your question is quite unclear. I suppose 989 and 999 will return 1. Because you only deal with number, so the solution is:
Create a boolean array with 9 element, from 0-9, named isChecked
Initialize it with false.
Whenever you found a matching number, say 9, turn the boolean element to true, so that you don't count it again (isChecked[9] = true).
Here is the code:
var isChecked = [];
function resetArray(input) {
for (var i = 0; i < 10; i++) {
input[i + ''] = false;
}
}
resetArray(isChecked);
var firstNumber = '989',
secondNumber = '999',
correctNumbers = 0,
fNum, sNum;
for (var i = 0; i < firstNumber.length; i++) {
fNum = firstNumber.charAt(i);
// Skip already checked numbers
if (isChecked[fNum]) {
continue;
}
for (var j = 0; j < secondNumber.length; j++) {
sNum = secondNumber.charAt(j);
if (fNum == sNum && !isChecked[sNum]) {
correctNumbers++;
isChecked[sNum] = true;
}
}
}
console.log(correctNumbers);
Tested on JSFiddle.
If you find anything unclear, feel free to ask me :)
(except maybe declaring an array and putting all the repeated numbers in there and only incrementing it if none of the numbers match, but that's super inefficient)
That approach is a good one, and can be made efficient by using a HashSet of Integers. Everytime you encounter a common digit, you do a contains on the set to check for that digit (gets in HashSets are of constant-time complexitiy - O(1), i.e. super quick), and if it's present in there already, you skip it. If not, you add it into the set, and increment your correctNumbers.
I believe this would help
int found=0; for (int i = 0; i < mString.length(); i++) {
for (int j = 0; j < nString.length(); j++) {
if (mString.charAt(i) == nString.charAt(j)) {
if(found==0){
correctNumbers++;
}
}
}
}
You could try making another 1D array of
int size = nstring.length() * mstring.length();
bool[] array = new bool[size];`
and then have that store a boolean flag of whether that cell has been updated before.
you would find the unique index of the cell by using
bool flag = false
flag = array[(i % mString.length()) + j)];
if(flag == true){
<don't increment>
}else{
<increment>
array[(i % mString.length()) + j)] = true;
}
you could also do this using a 2d array that basically would act as a mirror of your existing table:
bool[][] array = new bool[mstring.length()][nString.length()];
Why not just use the new stream api? Then it's just that:
Arrays.stream(mString).flatMapToInt(s -> s.chars()).distinct().count();
I'll explain:
Arrays.stream(mString) -> Create stream of all strings.
flatMapToInt -> create single concatenated stream from many IntStreams
s -> s.chars() -> Used above to create streams of characters (as ints)
distinct -> remove all duplicates, so each character is counted only once
count -> count the (unique) characters

Choose to loop infinitely if a number equals 0 or loop until some number if that number is greater than 0 - Java

I want to loop infinitely using a for loop if a number equals 0, and loop until that number number if the number is greater than 0. Here's the code to help visual what I'm getting at.
for (int i = 0; i < this.getNumRounds(); i++) {
// 30 some lines of code
}
or
for ( ; ; ) {
// 30 some lines of code
}
if getNumRounds() is greater than 0, do the first loop, if it equals 0, do the second. I would prefer to do this without copying and pasting my 30 some lines of code twice and using an if statement seeing as the code is redundant, though I could use a function to take out that redundancy, but I'm looking to see if there's another option.
Use the powerful ternary operator:
for (int i = 0; this.getNumRounds() == 0 ? true : i < this.getNumRounds(); i++) {
// 30 some lines of code
}
As noted in the comments by yshavit, there is a shorter, cleaner way of expressing this:
for (int i = 0; this.getNumRounds() == 0 || i < this.getNumRounds(); i++) {
// 30 some lines of code
}
Have you thought about using a while loop instead?
int i = 0;
while(i < this.getNumRounds() || this.getNumRounds() == 0) {
//some 30 lines code
i++
}
So you want something like this:
int num = //whatever your number equals
if (num == 0) {
boolean running = true;
while (running) {
doLoop();
}
} else {
for (int i = 0; i < num; i++) {
doLoop();
}
}
private void doLoop() {
//some 30 lines of code
}
This code puts the contents of the loop in a separate method and checks if the number is equal to 0. If it is, the program runs the doLoop() method forever. Otherwise, it runs until i equals the number.
While it would be better to just create a method and use an if-statement you could add an if statement inside the for-loop to decrease i every iteration. It would look like:
for (int i = 0; i <= this.getNumRounds(); i++) {
if(this.getNumRounds() == 0){
i--;
}
// 30 some lines of code
}
Notice I changed i < this.getNumRounds() to i <= this.getNumRounds. This way if the number of rounds is zero then the loop will be called.
You could do the following.
for (int i = 0; i < this.getNumRounds() || i == 0; ++i) {
do {
// 30 lines of code
} while (this.getNumRounds() == 0);
}
If getNumRounds is non-trivial to compute, consider pulling it out of the loop and calling it only once.

Doesn't enter in the "for-loop"?

Here is my code :
private String SerialNo;
private String FirmVersion;
public String GetSerial(int[] Data){
System.out.println("GetSerial Debug : Data => "+Data);
for (int i = 2;i==13;i++){
System.out.println("In the FOR => ok ");
if (i != 9){
SerialNo = SerialNo + Data[i];
}
if (i == 9){
SerialNo = SerialNo + ".";
}
}
System.out.println("SerialNo => "+ SerialNo);
return SerialNo;
}
My problem : I can't "enter" in the FOR
So my sysout of "In the FOR => ok", never shows and all the "actions" aren't done.
What am I doing wrong ?
ps : I'm sure that I'm compiling the right file.
The loop condition is never satisfied; i = 2 in the begin, the first check would fail, so all the loop would fail. Maybe it should be changed for:
for (int i = 2; i <= 13; ++i)
Examine your for statement:
for (int i = 2; i==13; i++)
This actually means the following:
assign 2 to i
Check whether i equal to 13. If yes, continue loop, exit otherwise.
Since i is not 13 in the first iteration of loop you never enter it. I believe that you wanted to write
for (int i = 2; i <= 13; i++)
In this case you will iterate from 2 to 13 inclusively. The condition of for loop means "do I have to remain iterating?" and not "do I have to escape?"
Change for (int i = 2; i == 13; i++) to for (int i = 2; i <= 13; i++).
The second argument is the loop condition which has to be true to run the loop.
Your condition became false at first iteration so control never goes to loop body.
for loop syntax:
for(initialization; condition; increment/ decrement){
//your code
}
So here you will have to use some appropriate condition to enter into the loop.
So for example :
for (int i = 0; i <= 13; i++) // for 0 to 13 increment
or
for (int i = 10; i >= 0; i--) // for 10 to 0 decrement
for (int i = 2;i==13;i++){}
It enters but failed at first condition check and for-loop exits.
It should be -
for (int i = 2;i<=13;i++)
You have initialized i=2
for (int i = 2;i==13;i++)
And condition is i==13 which will become false ultimately flow never enter into for loop
try to change the code like this
for (int i = 2;i<=13;i++)
Statement is not good should be like the one below:
for (int i = 2; i<13; i++) or for (int i = 2; i<=13; i++)
See compared simple while loop in the case of your for loop.
Think about int i =2; value set and i == 13 condition
Do you think it will work?
for (int i = 2;i==13;i++){
//do something
}
Same to below *while loop* explanation
int i = 2;
while (i == 13) {
//do something
i++;
}
I am sure it will work
for (int i = 2;i < 13;i++){
//do something
}
Same to below **while loop**
int i = 2;
while (i < 13) {
//do something
i++;
}
The flow of the for loop is: init statement-> condition check-> goes inside loop or outside depending on the condition outcome.
Here, since you've said i=2 ,then i==13 is false; it'll never go inside the loop.
You could use the ?: operator in the for loop and then modify your if statements a bit I guess..

When trying to read multiple inputs using a scanner, I can't make it read integers and chars

Here is the code
public void promptUser(){
Scanner scan = new Scanner(System.in);
System.out.print("Pick a coordinate [row col] or press [q] to quit.");
int row = 0;
int row = 0;
String line = scan.nextLine().trim();
String[] contents = line.split(" ");
if (contents[0] == "q"){
isRunning = false;
System.exit(0);
}// if quit
if (contents.length < 1 || contents.length > 2){
System.out.print("Invalid Response. Try again.");
promptUser();
}// if wrong amount of input
else {
row = Integer.parseInt(contents[0]);
col = Integer.parseInt(contents[1]);
}// parse ints else
if (inBounds(row, col) == true){
if(!(board[row][col] == 'c'){
click(row, col);
}// has been clicked
}// in bounds?
else{
System.out.print("Invalid response. Try again.");
promptUser();
}// else error
}// promptUser method
and here is the error:
Exception in thread "main" java.lang.NumberFormatException: For input string: "q"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:481)
at java.lang.Integer.parseInt(Integer.java:514)
at Minesweeper.promptUser(Minesweeper.java:197)
at Driver.main(Driver.java:12)
This method is meant to get input from the user, check it for errors. If it is correct, then it should exit the program if "q" is entered and "click" the coordinate if it is two integers inside the bounds that have not already been clicked. I can't enter 'q' without this error. I also get an outOfBounds exception with any integers entered. (Yes, this is homework, and I've searched long and hard, but haven't quite found out how to fix this.)
Any and all help is GREATLY appreciated.
Here is the inBounds method I use, and the initialize (where the board is initialized)
public void initialize(){
isRunning = true;
board = new char[this.rows][this.cols];
for (int i = 0; i < board.length; i++){
for(int j = 0; j < board[i].length; j++){
board[i][j] = 'e';
}
}
mineBoard = new boolean[this.rows][this.cols];
for (int i = 0; i < mineBoard.length; i++){
for (int j = 0; j < mineBoard[i].length; j++){
mineBoard[i][j] = false;
}
}
Random bob = new Random();
Random sally = new Random();
for (int i = mines; i > 0; i--){
int mineX = bob.nextInt(10);
int mineY = sally.nextInt(10);
if (mineBoard[mineX][mineY] == false){
mineBoard[mineX][mineY] = true;
}
else{
i++;
}
}
}
That's the initialize...
and here is the inBounds
private boolean inBounds(int row, int col){
if (row < 0 || row > board.length){
return false;
}
if (col < 0 || col > board[0].length){
return false;
}else
return true;
}
is there anything else that would help? I fixed the problem with q, but I keep having problems with the out of bounds thing.
Use contents[0].equals("q"). Otherwise, the equality will fail, hence your NumberFormatException later on. You can learn more about this common mistake.
Essentially what is happening is that you have two Strings -- the literal "q", and the split result from the user input. While both may be semantically equivalent (i.e. contents[0].equals("q")), they more than likely will not be identical, since one is constructed from user input. Since they aren't identical objects, == will fail, causing your code flow to continue on. It will attempt to invoke Integer.parseInt("q") -- which fails with a NumberFormatException because it's an invalid number.
Your "outOfBounds exception" is most likely ArrayIndexOutOfBoundsException, which is likely caused by your row, col being too big for your array (in fact, they're outside of it -- hence, out of bounds). To verify this, you'll need to show more code.
Additionally, you don't need to write if (inBounds(row, col) == true). Any boolean expression b will satisfy the tautology b <=> b == true, i.e. its merely the identity. You can just write the more concise and simple if (inBounds(row, col)).
Furthermore, you should avoid the recursion you have right now. In the case of repeated invalid response, a StackOverflowException can be triggered. Be careful when using unbound recursion as such, as the Java call stack is bounded.
The problem you are having is experienced quite commonly when programmers are starting out. Basically, the == operator compares the references of the two object you are comparing. For Strings (and other objects) this is almost always false. In your case, you should use something like:
contents[0].equals("q")
This will call the equals method of the String class, which will correctly compare the content of the two Strings.

println not happening when called from a decision statement within a method (in Java)

I have come across a somewhat annoying problem during a project. I created this sample class to describe the issue which I am having.
public class Test {
public static void Testing(){
for (int i = 0; i >= 5; i++) {
System.out.println(i);
}
System.out.println("hello world.");
}
public static void main(String[] args) {
Testing();
}
}
My issue is that the only output from this program is simply "hello world."
Could anyone explain the reason why my println statement inside the for loop is being completely ignored? I have searched on Google but it is hard to describe in a search.
Thanks a lot!
The for loop should be
for (int i = 0; i <= 5; i++)
Hai Buddy. the problem is logical.look at the for loop closely for (int i = 0; i >= 5; i++)
The for loop should be
for (int i = 0; i <= 5; i++)
I think the problem is that you loop never executes since your condition is that I is at least 5, but you start it at zero. Try changing it to be less than or equal to five and see if that fixes it.
change the for loop
for(int i = 0; i <= 5; i++)
read again:
for (int i = 0; i >= 5; i++)
i defaults to zero, and the for iterates while i is more or equal to 5.
Because your condition (i >= 5) never is true, since you set i to 0. The condition should be i <= 5.
for (int i = 0; i <= 5; i++) //You have put > sign it should be < sign
{
System.out.println(i);
}
The reason is that your for loop is never executed. On first step i = 0 i>=5 = false so the body of the for is never executed
When main method invoke you method it first initialize the value of i with 0 then its go for the condition i>=5, Which looks like 0 >= 5 which always be 'false'.So you inner print statement never be execute.
The for loop never execute because the at the beginning i is checked to see if it equal or greater than 5 (which it is not, i=0)
for (int i = 0; i >= 5; i++)
then the loop terminates and the next statement is executed.

Categories

Resources