if statement constantly printing - java

My if statement is acting weird, instead of printing only when wrong is greater than 6, it is constantly printing "dead" every time. Any ideas on why that is? I've updated the code so you can better understand my logic.
int j = 0;
String line = "";
for(j = 0; j<64; j++) {
wordLength[j] = wordList[j].length();//gets length of words in wordList
}//end for
int f = 2;//change num to change level
int m = 0;
//creates line first then put into .setText
while(m<wordLength[f]) {
line += "__ ";
m++;
}//end for
jlLines.setText(line);
tf.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {//when enter key pressed
JTextField tf = (JTextField)e.getSource();
letter = tf.getText();
jlLetsUsed.setText(jlLetsUsed.getText() + letter + " ");//sets jlabel text to users entered letter
char[] jlabelText = jlLines.getText().toCharArray();//converts string to character array (array length is length of string)
char userEnteredChar = letter.charAt(0);
int wrong = 0;
int level = 2;//change num to change level
int i = 0;
for(i = 0; i<wordList[level].length(); i++){
if(wordList[level].charAt(i) == userEnteredChar){
jlabelText[3 * i] = ' ';
jlabelText[3 * i + 1] = userEnteredChar;
jlLines.setText(String.valueOf(jlabelText));
}else{
wrong++;
System.out.println(wrong);
}if(wrong >= 6){
System.out.println("dead");
break;
}
}//end for
}//end actionPerformed method

Evidently wrong is always >= 6. One possibility is that level is longer than 1 character and thus the contains check is always false. That's if it's always 'wrong' even with a 'right' guess.
The more likely possibility is that because the check where you increment wrong is inside the loop, any time wordList[level] is 6 or more characters in length and does not contain letter, wrong will be incremented 6 or more times.
You probably should put the check outside the loop.
for(int i = 0; i<wordList[level].length(); i++){
if(wordList[level].charAt(i) == userEnteredChar){
jlabelText[3 * i] = ' ';
jlabelText[3 * i + 1] = userEnteredChar;
jlLines.setText(String.valueOf(jlabelText));
}
}
if(!wordList[level].contains(letter)){
wrong++;
}
if(wrong>=6){
System.out.println("dead");
}
By the way, an obvious suggestion here is that if you are checking contains, you might as well check it first and skip the 'revealing' loop somehow if contains is false.
It looks like wrong should probably be a field somewhere. Shown here I've declared it as a field on the ActionListener. Don't put it on the ActionListener, put it somewhere else, preferably on the containing class. I don't see where else to put it though and this may work initially. The point is to keep track of 'wrong' guesses outside the single guess in actionPerformed. That means you have to declare it somewhere outside the method scope.
tf.addActionListener(new ActionListener() {
int wrong;
#Override
public void actionPerformed(ActionEvent e) {
JTextField tf = (JTextField)e.getSource();
char userEntry = tf.getText().charAt(0);
jlLetsUsed.setText(jlLetsUsed.getText() + userEntry + " ");
int level = 2;
if (!wordList[level].contains(String.valueOf(userEntry))) {
wrong++;
if (wrong >= 6) {
System.out.println("dead");
}
return;
}
char[] jlabelText = jlLines.getText().toCharArray();
for (int i = 0; i < wordList[level].length(); i++) {
if (wordList[level].charAt(i) == userEntry) {
jlabelText[3 * i] = ' ';
jlabelText[3 * i + 1] = userEntry;
}
}
jlLines.setText(String.valueOf(jlabelText));
}
});

Related

Is there a way to make it output the values of result in my code?

I'm working on my university assignment which requires me to program an eviction algorithm. I am new to programming and have only done Python before. Below is what I have done so far. The code compiles fine but I am not getting the output that I was expected to get.
getting user input and then calling the method for no eviction:
System.out.println();
System.out.println("Cache content: ");
print_array(org_cache, size);
System.out.println("Request sequence: ");
print_array(request, count);
try {
copy_array(org_cache, cache, size);
System.out.println("no_evict");
no_evict(cache, size, request, count);
}
catch (Exception e) {
System.out.println("ERROR: no_evict");
the method:
static void no_evict(int[] cache, int c_size, int[] request, int r_size) {
int i = 0;
boolean found = false;
String result = "";
String resultHit = "";
String resultMiss = "";
for(int x = 0; x < r_size; x++) { //for loop goes through every requests
while(i < c_size || found == false) { //while loop brings a page through every cache value
if(request[x] == cache[i]){
found = true;
} else {
i += 1;
}
}
if(found == true) {
result += "h";
resultHit += "h";
} else {
result += "m";
resultMiss += "m";
x += 1; //proceeds to next value in request sequence
}
}
System.out.println(result);
System.out.println(resultHit.length() + "h " + resultMiss.length() + "m");
}
it does not output the result string but instead outputs this:
Cache content:
20 30 10 5 40
Request sequence:
20 30 10
no_evict
You will notice that your program doesn't actually exit. This is because it's stuck in an infinite loop, just as what would happen in Python.
If you run it in a debugger or hit Ctrl-\ in a console, you'll see that it's stuck in this loop:
while(i < c_size || found == false) { //while loop brings a page through every cache value
if(request[x] == cache[i]){
found = true;
} else {
i += 1;
}
}
The condition is true as long as i < c_size because you used ||, logical "or". You probably intended to use &&, so that find = true will break the loop.
PS: The Java compiler doesn't care about indenting, but humans do. Please use your editor's indenting function to make the code easier to read.
As #that other guy mentioned, you are using || instead of &&.
But you don't need the second qualifier. Just use:
i = 0;
while(i < c_size ) {
if(request[x] == cache[i]){
found = true;
break;
} else {
i += 1;
}
}
or
for ( int i=0; i < c_size; i++ ) {
if ( request[x] < cache[i] ) {
found = true;
break;
}
}
There is another problem with your algorithm: you initialise i right at the beginning but never reset it to zero.
You probably want to move the int i = 0 statement between the for and the while statement.

How to print out the index of a boolean array?

I'm trying to get all of the indexes of a Boolean array to be printed out where its element is true. The end goal is to be able to find a prime number of the indexes (where I change each index number that isn't prime to false in the array) then print out only what is left of the prime numbers of the indexes of the array.
The very first step I'm just trying to do is at least to get some integer index to print out, but nothing seems to be working and I don't know what is wrong.
public class PriNum{
private boolean[] array;
public PriNum(int max){
if (max > 2){ //I don't have any problems with this if statement
throw new IllegalArgumentException();
}
else{
array = new boolean[max];
for(int i = 0; i < max; i++){
if(i == 0 || i == 1){ //Automatically makes 0 and 1 false
//because they are not prime
array[i] = false;
}
else{
array[i] = true;
}
}
toString(); //I know for sure the code gets to here
//because it prints out a string I have
// there, but not the index
}
}
public String toString(){
String s = "test"; //this only prints test so I can see if
//the code gets here, otherwise it would just be ""
for (int i = 0; i < array.length; i++){
if(array[i] == true){
s = s + i; //Initially I tried to have the indexes returned
//to be printed and separated by a comma,
//but nothing comes out at all, save for "test"
}
}
return s;
}
}
EDIT: Included is the driver class that's requesting the print of the class PriNum
class Driver{
public static void main(String [] args){
PriNum theprime = null;
try{
theprime = new PriNum(50);
}
catch (IllegalArgumentException oops){
System.out.println("Max must be at least 2.");
}
System.out.println(theprime);
}
}
I tried running this, and the first change that needs to happen is to set this argument:
if(max < 2)
Then, if I'm reading this correctly: 0 and 1 are false. Every index after that is true. The output is fine as I see it. Just all the numbers crunched as a continuous list.
To get a better output, put a space between indexes:
if(array[i] == true){
s = s + " " + i;
}
You may even just output to screen directly as
if(array[i])
System.out.print( i );
numbers is initialized without declaration, array is declared but not initialized anywhere in your code. You have also a syntax error after array[i] = true, should be curly brace...

How do i remove the last comma when i print numbers within a loop?

So I made this to print primes between two numbers of my choice; however, it prints out a comma after the last number and I don't know how to take it off.
Example
in: 0 10
out: 2, 3, 5, 7,
I want 2,3,5,7
Scanner s = new Scanner(System.in);
int a = s.nextInt();
int b = s.nextInt();
for (int i = a; i <= b; i++){
int j;
for (j = 2; j<i; j++){
int p = i%j;
if(p==0){break;}
}
if(i == j){System.out.printf("%d,", i);}
}
}
Use a boolean to keep track of whether you've printed anything yet. Then your format string could be something like
anythingPrinted ? ",%d" : "%d"
That is, only include the comma in the format string if there's something printed.
Use a StringBuilder and write to the console at the end of your program.
StringBuilder sb = new StringBuilder();
for (int i = a; i <= b; i++){
int j;
for (j = 2; j<i; j++){
int p = i%j;
if(p==0){break;}
}
if(i == j){
// If the length of the StringBuilder is 0, no need for a comma
if(sb.length() != 0) {
sb.append(",");
}
sb.append(i);
}
}
System.out.println(sb);
This might seem like overkill, and for many cases it might be, but I have been writing a source code transcoder and I find this situation coming up a lot. Where I need commas in between values, or a prefix value which is only printed once. So I found it handy to create a class which simplifies things.
Again, you wouldn't probably want to use this if you code had one or two print loops in it, but maybe if you had more than a few. Perhaps you would remove in "on first" part if you were never going to use it.
public class FirstPrintOptions {
private PrintStream printStream;
private String onFirst;
private String remaining;
private boolean trip = false;
public FirstPrintOptions(PrintStream printStream, String onFirst, String remaining) {
this.printStream = printStream;
this.onFirst = onFirst;
this.remaining = remaining;
}
public void print() {
if (!trip) {
if (onFirst != null) {
printStream.print(onFirst);
}
trip = true;
} else {
if (remaining != null) {
printStream.print(remaining);
}
}
}
}
Then use it like this..
FirstPrintOptions firstPrintOptions = new FirstPrintOptions(System.out, null, ",");
for (int x=0;x<10;x++) {
firstPrintOptions.print();
System.out.print(x);
}
The results are..
0,1,2,3,4,5,6,7,8,9
I was testing and I came up with this. I was using compilejava.net so scanner doesn't work. I bypassed that part and just set a and b manually. Basically, it builds a string with the numbers and ends in a comma. Then it prints a substring including everything except the last comma.
import java.util.*;
public class HelloWorld {
public static void main(String[] args) {
//Scanner s = new Scanner(System.in);
int a = 2;
int b = 18;
String c = "Output = ";
for (int i = a; i <= b; i++){
int j;
for (j = 2; j<i; j++){
int p = i%j;
if(p==0){break;}
}
if(i == j){c=c+ Integer.toString(i) + ",";}
}
System.out.print(c.subSequence(0, c.length()-1));
}
}
this program for finding factors of a number
for(i=1;i<=number;i++)
{
if(number%i==0)
{
system.out.print(i);
if(i!=0)
{system.out.print(",");}
}
}
so i get the output for 10 as
1,2,5,10

How to tackle the Codingbat String-2 oneTwo challenge?

Here is the problem statement:
Given a string, compute a new string by moving the first char to come after the next two chars, so "abc" yields "bca". Repeat this process for each subsequent group of 3 chars, so "abcdef" yields "bcaefd". Ignore any group of fewer than 3 chars at the end.
Here is my code:
// oneTwo("abc") → "bca"
// oneTwo("tca") → "cat"
// oneTwo("tcagdo") → "catdog"
public String oneTwo(String str) {
String x = "";
if (str.length() < 3) {
return "";
// return empty
} else if (str.length() == 3) {
String s = str.substring(1, str.length());
x = s + str.substring(0, 1); // last two + first char
} else if (str.length() > 3) {
int third = 2;
// start with the third element index of 2
for (int i = 0; i < str.length(); i++) {
if (i == third) {
// given three chars substring first char
// substring last two chars and add that to x
x += (str.substring(third - 1, third + 1) +
str.substring(third - 2, third - 2 + 1));
third += 3;
//work with this line but why??????
}
//third +=3;
// doesn't work with this line but why???????
}// end of for loop
}
return x;
// return modified string x
}
With third +=3 inside of if statement work but when I put that outside of if statement I don't get the desired output. I don't really understand why?
Hope this helps:
public String oneTwo(String str) {
String str2 = "";
for(int i=0; i<str.length()-2; i+=3) {
str2 = str2+str.substring(i+1,i+3)+str.charAt(i);
}
return str2;
}
Because putting it outside the loop will cause third to be increased far too often. After the first iteration i is 0, third is 5, next iteration yields i=1, third=8; i=2, third=11; i=3, third=14, etc. -> i will never reach third.
I would improve your code by dropping the entire if-statement, remove third all together and simply increment by 3 in the for-loop:
for( int i = 2; i < str.length(); i+=3){
x += (str.substring(third-1, third+1) +
str.substring(third-2, third-2 + 1));
}
If I am not misinterpreting your code you are missing logic for leaving the last characters alone if they are not part of group of three characters.
If you face such effects take a piece of paper and write down the values of the variables after each line of your code.
The if block creates an alternative execution path if the condition is true which is in every third loop iteration.
Anything behind the if block is executed in every loop iteration.
So when the line in question is inside the if block (before the closing brace) the value in variable third is only changed every third loop iteration.
When you move the line behind the closing brace the assignment is outside the if block and therefore executed every loop iteration.
For the comment = //work with this line but why??????
The value of "third" variable gets changed in the for loop only with i is equal to third character, otherwise the value of third will keep on increasing eg.
when i = 0, third = 2
when i = 1, third = 5
when i = 2, third = 8
so the if statement never gets triggered and hence it doesn't work. Hope this makes sense.
PS - I highly recommend using IDE debugger to understand this properly.
PS - It's better to use charAt method as compared for substring method for performance reason
public String oneTwo(String str) {
String temp = "";
String result = "";
int i = 0;
while (str.substring(i).length() >= 3) {
temp = str.substring(i, i + 3);
result += temp.substring(1) + temp.charAt(0);
i += 3;
}
return result;
}
public String oneTwo(String str) {
String str1 = "";
if(str.length()<3){
return str1;
}else if(str.length()>=3){
for(int i =0; i<str.length()-2; i=i+3){
str1 = str1 + str.substring(i+1,i+3)+ str.substring(i,i+1);
}
}
return str1;
}
public String oneTwo(String str) {
if(str.length()<3)return "";
return str.substring(1,3)+str.substring(0,1)+oneTwo(str.substring(3));
}
this is fairly simple as a recursive problem
public String oneTwo(String str) {
String newThreeChars = "";
if(str.length()<3){
return newThreeChars;
}
for(int i=0; i<str.length()/3; i+=3){
String threeChars = str.substring(i,i+3);
String redesigned = threeChars.substring(1) + threeChars.charAt(0);
newThreeChars +=redesigned;
}
return newThreeChars;
}
Another solution to look at...
public String oneTwo(String str) {
int i = 0;
String result = "";
Character tmpChar = '\0';
while(i <= str.length()-3){
tmpChar = str.charAt(i);
result = result + str.charAt(i+1) + str.charAt(i+2) + tmpChar;
tmpChar = '\0';
i = i + 3;
}
return result;
}
First, We loop through each letter of the given String just stopping shy of the last two letters because the word we are looking for is three letters long. Then, we are returning true if there is two letter "b"'s exactly one character apart.
public boolean bobThere(String str) {
for (int i = 0; i < str.length() - 2; i++) {
if (str.charAt(i) == 'b' && str.charAt(i+2) == 'b')
return true;
}
return false;
}
For string concatenation in a loop use StringBuilder:
public String oneTwo(String str) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length() - 2; i += 3) {
sb.append(str.charAt(i + 1)).append(str.charAt(i + 2)).append(str.charAt(i));
}
return sb.toString();
}

Issues with While loop condition

I am writing a program that reads a text file which contains match results, and then should output them in a table. I have a While loop within a While loop:
Scanner fileread1 = new Scanner(new File("demo.txt"));
int x = 0;
int y = 22;
int i = 0;
while (x <= y) {
while (fileread1.hasNext()) {
fileinput = fileread1.nextLine(); // this reads the next line of
// from the file
String line = fileinput;
String[] split = line.split(":");
boolean result = false;
int homescore1 = 0;
int awayscore1 = 0;
int goalsscored = 0;
boolean att = false;
boolean htt = false;
int atscore = 0;
int htscore = 0;
// When the text line is read, it is then split into four sections.
if (split.length == 4) {
// String text = line.trim();
String userteam = userteaminput;
String hometeam = split[0].trim();
String awayteam = split[1].trim();
String home_score = split[2].trim();
String away_score = split[3].trim();
// this is a test to try convert the goals string into a
// integer. If this fails, the result is not
// not valid and does not get outputted to the console.
try {
homescore1 = Integer.parseInt(home_score);
awayscore1 = Integer.parseInt(away_score);
result = true;
}
catch (NumberFormatException exception) {
// if the try is not able to convert, this will run
errors++;
}
if (userteam.equals(Teams.get(i))) {
if (awayteam.equalsIgnoreCase(userteam)) {
att = true;
games++;
goalsfor = goalsfor + awayscore1;
goalsagainst = goalsagainst + homescore1;
}
if (att == true && awayscore1 > homescore1) {
atwc++;
gameswon++;
}
else if (att == true && awayscore1 < homescore1) {
htwc++;
gameslost++;
}
else if (att == true && awayscore1 == homescore1) {
gamesdrawn++;
}
if (hometeam.equalsIgnoreCase(userteam)) {
htt = true;
totaluser++;
games++;
goalsfor = goalsfor + homescore1;
goalsagainst = goalsagainst + awayscore1;
}
if (htt == true && homescore1 > awayscore1) {
atwc++;
gameswon++;
}
else if (htt == true && homescore1 < awayscore1) {
htwc++;
gameslost++;
}
else if (htt == true && awayscore1 == homescore1) {
gamesdrawn++;
}
}
}
else {
errors++;
}
}
// ********************************************************************
// Leeds IF Statement
// ********************************************************************
if (Rhinos.equals(Teams.get(i)) {
Rhinos.goalsfor = Rhinos.goalsfor + goalsfor;
Rhinos.gameswon = Rhinos.gameswon + gameswon;
Rhinos.gameslost = Rhinos.gameslost + gameslost;
Rhinos.goalsagainst = Rhinos.goalsagainst;
Rhinos.gamesplayed = Rhinos.gamesplayed + games;
}
else if (Bulls.equals(Teams.get(i)) {
Bulls.goalsfor = Bulls.goalsfor + goalsfor;
Bulls.gameswon = Bulls.gameswon + gameswon;
Bulls.gameslost = Bulls.gameslost + gameslost;
Bulls.goalsagainst = Bulls.goalsagainst;
Bulls.gamesplayed = Bulls.gamesplayed + games;
}
x++;
i++;
goalsfor = 0;
gameswon = 0;
gameslost = 0;
gamesagainst = 0;
}
I know that there are only ever going to be 22 teams that have results in the text file supplied, so the first loop should run for 22 times.
The inner loop, will continue whilst the file provided has a next line. The text file may sometimes have more lines of results then other files. Within this loop, I have a reference to an Array item:
if (userteam.equals(Teams.get(i)))
In the first run, this will refer to 0 in my Array which, for the record, is Leeds Rhinos. Once the inner loop has completed, it then moves onto the outer loop - this deals with the results just recorded. If the current team is Leeds Rhinos, it should then add the values. The i should then have 1 added, so for the next loop, it refers to the index of 1 of the array, not 0. (I have more IF statements here, all identical but refer to other teams) Variables get set back to 0, ready for the next run.
The issue I have, is that i does not seem to have 1 added each time it runs through, so I am only getting results passed through for one team. If I manually specify which array index to look (say 3) it will run through, and the team will have their results successfully recorded.
Is there a way I can get 1 added to i every time it loops? I'm not sure if this is the correct java loop to use, but to me, seemed the most logical. There are some objects not declared here - this is just a snippet of the code, left out the declarations as I know they work, and there's a lot declared.
If you're worried about failed incrementation, it would be better to use a For loop.
Instead of having a while (x < y) and sticking an increment statement somewhere in your code,
a
for (i = 0; i < y; i++) { // do tests here }
loop will guarantee that you always increment and run the test for the next team.
For future reference, when using while loops and incrementing, the incrementation is almost always done at the END of the while loop, and not somewhere in between. The incrementation statement should also almost never be in a conditional statement (which might cause an infinite loop).
Your question is not clear. But let's point out something in the code you provided
1) What is the difference between your if and else if statement? They are checking exact same thing
if (userteam.equals(Teams.get(i)) {
Rhinos.goalsfor = Rhinos.goalsfor + goalsfor;
Rhinos.gameswon = Rhinos.gameswon + gameswon;
Rhinos.gameslost = Rhinos.gameslost + gameslost;
Rhinos.goalsagainst = Rhinos.goalsagainst;
Rhinos.gamesplayed = Rhinos.gamesplayed + games;
}
else if (userteam.equals(Teams.get(i)) {
Bulls.goalsfor = Bulls.goalsfor + goalsfor;
Bulls.gameswon = Bulls.gameswon + gameswon;
Bulls.gameslost = Bulls.gameslost + gameslost;
Bulls.goalsagainst = Bulls.goalsagainst;
Bulls.gamesplayed = Bulls.gamesplayed + games;
}
2) What are you doing with variable x, I don't see anywhere you are increasing it.
3) On very first run, when x<=y, the inner loop will finish reading all lines, so even if you increase the X some point, from second run the inner loop will not execute. As it already finished reading all lines. So no point doing this
Again if you provide some more inside on what you want to accomplish, may be with the sample text file data, that would probably help answering your question.
Thank you.
Your formatting is working against you here; properly indented, your code structure is something like this (note, I had to add in missing closing braces, }, at the end of the code you provided as I assume you just missed them when you copied your code over):
Scanner fileread1 = new Scanner(new File("demo.txt"));
int x = 0;
int y = 22;
int i = 0;
while (x <= y) {
while (fileread1.hasNext()) {
fileinput = fileread1.nextLine(); // this reads the next line of
/* stuff */
if (split.length == 4) {
/* stuff */
x++;
i++;
}
}
}
Your incrementation of x and i is nested within if (split.length == 4) {, meaning that x and i will only be incremented in that specific case and not at the end of each iteration of the inner while loop.

Categories