I have a bug in this block of code. The debugger suggest it´s cause is this line of code char chr = getSecretWord.charAt(i);
What this code does is look for a match between userInput and secretWord. I have the for loop to go through the length of the secretWord letters one by one, and if there is a letter matching return true. If not, return false... but the program crashes when it is suppose to just return false... I guess it is something with this line, but do not know exactly what getSecretWord.charAt(i);
private boolean isMatchingSecretWord(String userInput)
{
String secretWord = "";
String getSecretWord = getSecretWord();
for (int i = 0; i <= getSecretWord.length();i++)
{
char chr = getSecretWord.charAt(i);
secretWord = ""+chr;
if (secretWord.equals(userInput))
{
println("is true");
return true;
}
}
return false;
}
As an side note, is what I´ve done with this code correct, assigning the getSecretWorld() Method to a String so I can use the Strings method length()?
String getSecretWord = getSecretWord();
for (int i = 0; i <= getSecretWord.length();i++)
Debug code:
Exception in thread "Thread-4" java.lang.StringIndexOutOfBoundsException: String index out of range: 4
at java.lang.String.charAt(String.java:686)
at Hangman.isMatchingSecretWord(Hangman.java:49)
at Hangman.userInput(Hangman.java:34)
at Hangman.run(Hangman.java:20)*
for (int i = 0; i <= getSecretWord.length(); i++)
should be:
for (int i = 0; i < getSecretWord.length(); i++)
// ^^^
// see here
The valid indexes for an n-character string (or an n-element array) are 0 through n-1 inclusive.
So, if your secret word is xyyzy, the valid indexes are zero through four. Your original loop iterates with i set to zero through five, hence the problem.
But there seems to be a lot of unnecessary code in there, when you could get away with something simple.
First, I would remove a source of confusion - the function name sounds like the user input and the secret word have to match completely whereas your comment indicates otherwise:
Thanks, this works. But the reason for the loops is that the user enters one letter, I want to see if that letter is within the SecretWord. (it´s a hangman game).
In that case, you simply want to see if the single character exists in the secret word. I would change the function name to suit and, even then, it can be done with a lot less code:
private boolean isInSecretWord (String userInput) {
String secretWord = getSecretWord();
return secretWord.contains(userInput);
}
You were getting out of bounds error as your for loop wasn't looping correctly, I have modified it so that the loop doesn't go out of bounds and also your secretWord variable wasn't populating correctly, the code should now work as intended :)
private boolean isMatchingSecretWord(String userInput)
{
String secretWord = "";
String getSecretWord = getSecretWord();
for (int i = 0; i < getSecretWord.length();i++)
{
char chr = getSecretWord.charAt(i);
secretWord = secretWord + chr;
if (secretWord.equals(userInput))
{
println("is true");
return true;
}
}
return false;
}
Related
My problem is that I need to identify characters which differ between the two given strings in a visually striking way. Output the two input strings on two lines, and then identify the differences on the line below using periods (for identical characters) and asterisks (for differing characters). For example:
ATCCGCTTAGAGGGATT
GTCCGTTTAGAAGGTTT
*....*.....*..*..
I have tried to write two string with each other but I dont know how to make the program check for every character in the string and see if those match
This is what I have done so far :/
System.out.println("String 1: ");
String var1 = Scanner.nextLine();
System.out.println("String 2: ");
String var2 = Scanner.nextLine();
if (same (var1, var2))
System.out.println(".........");
else
System.out.println("********");
public static boolean same (String var1, String var2){
if (var1.equals(var2))
{
return true;
}
else
{
return false;
}
Can anyone help me with this?
You need to loop through your Strings and compare characters one by one. To run through your list you can make a for-loop. Use an int as counter and use the method length() to obtain your string size.
for(int i=0; i<string1.length(); i++ {
// do stuff
}
Then since you have a counter going through all position of your string, you can obtain the character at a specific position in this string using the method charAt()
char char1 = string1.charAt(i);
Then compare the character to check if they are the same. If they are print a dot . if they're not print an asterisk *
if(char1 == char2) {
System.out.print(".");
} else {
System.out.print("*");
}
In the above part I supposed your two string have the same size. If it's not the case, you can first determine which one is the smallest (and so which is the biggest) :
String smallestString;
String biggestString;
if(string1.size() > string2.sise()) {
smallestString = string2;
biggestString = string1;
else {
smallestString = string1;
biggestString = string2;
}
Then make your for loop go through the smallest String, otherwise you will face IndexOutOfBoundsException.
for(int i=0; i<smallestString.length(); i++ {
// do stuff
}
And the end of this for loop print asterisks for the characters that left in the biggest String
for(int j=smallestString.length(); j<biggestString.length(); j++) {
System.out.print("*");
}
This is what I've come up with.Mind you there are better ways to do this and I've just written it with as much effort as you put in your question.
public class AskBetterQuestion{
public static void main(String[] args) {
// TODO Auto-generated method stub
String w1="ATCCGCTTAGAGGGATT";
String w2="GTCCGTTTAGAAGGTTT";
char[] first = w1.toCharArray();
char[] second = w2.toCharArray();
int minLength = Math.min(first.length, second.length);
char[] out=new char[minLength];
for(int i = 0; i < minLength; i++)
{
if (first[i] != second[i])
{
out[i]='.';
}
else out[i]='*';
}
System.out.println(w1);
System.out.println(w2);
System.out.print(out);
}
}
I am trying to generate a String as a hint for the solution to a world solve.
This is what I have for generating the hint, but I am unsure of how to correct these errors. If the guess has the correct character guessed in the right place, the hint displays that character. If it has the letter in the word, it displays a "+" in the respective position. If the letter isn't in the word, a "*" gets returned.
For instance, if the solution to the puzzle is "HARPS", and the guess is "HELLO", the hint will be "H****". Likewise if the guess is "HEART", the hint will be "H*++*".
Also, wordLength is generated from another method that gives the amount of characters in the solution.
public String getHint(String theGuess) {
for (int index = 0; index < wordLength; index++) {
if **(theGuess.charAt(index)** = solution.charAt(index)) {
hint.**setCharAt**(index, theGuess.charAt(index));
} else if **(theGuess.charAt(index)** = solution.indexOf(solution)) {
**hint.setCharAt**(index, "+");
} else {
**hint.setCharAt**(index, "*");
}
}
return hint;
}
Errors are double starred.
For (theGuess.charAt(index) Eclipse is showing the following error message:
The left-hand side of an assignment must be a variable.
For hint.setCharAt, it tells me:
The method setCharAt(int, String) is undefined for the type String.
There are numerous problems in your code that need to be fixed:
= is used when you want to assign a new value to a variable. You want to use == when comparing two values.
setCharAt() is a method for StringBuilder, not String. This simplest solution is to just concatinate your new charater to the String using +=.
If you want to use StringBuilder, the following parts need to be fixed:
The second parameter for setCharAt() should be a character, not a string. You need to change the double quotes around "*" and "+" to single quotes like '*'
setCharAt() tries to replace a character at a specifc index. This will throw an error if the StringBuilder is shorter than the index position you are trying to replace. You can solve this by right away setting your StringBuilder to a string that is the correct length like
hint = new StringBuilder("*****").
Since you are always adding the the end of the builder though, you should really just use append() instead of setCharAt() and you won't need to worry about this index position problem.
(theGuess.charAt(index) == solution.indexOf(solution) does not search the entire solution string to see if it contains the current character. Instead, you can use indexOf() to check if the string contains the character. This link might help: How can I check if a single character appears in a string?
Here is a complete program with the code working:
public class HelloWorld
{
public static void main(String[] args)
{
OtherClass myObject = new OtherClass();
System.out.print(myObject.getHint("HEART"));
}
}
Option 1 - Add to the String using +=:
public class OtherClass
{
private String solution = "HARPS";
private int wordLength = 5;
public String getHint(String theGuess) {
String hint = "";
for (int index = 0; index < wordLength; index++) {
if (theGuess.charAt(index) == solution.charAt(index)) {
hint += theGuess.charAt(index);
} else if (solution.indexOf(theGuess.charAt(index)) > 0) {
hint += "+";
} else {
hint += "*";
}
}
return hint;
}
}
Option 2 - Use StringBuilder:
public class OtherClass
{
private StringBuilder hint;
private String solution = "HARPS";
private int wordLength = 5;
public String getHint(String theGuess) {
hint = new StringBuilder();
for (int index = 0; index < wordLength; index++) {
if (theGuess.charAt(index) == solution.charAt(index)) {
hint.append(theGuess.charAt(index));
} else if(solution.indexOf(theGuess.charAt(index)) > 0) {
hint.append('+');
} else {
hint.append('*');
}
}
return hint.toString();
}
}
This code should work:
public String getHint(String theGuess) {
StringBuilder hintBuilder = new StringBuilder(hint);
for (int index = 0; index < wordLength; index++) {
if (theGuess.charAt(index) == solution.charAt(index)) {
hintBuilder.setCharAt(index, theGuess.charAt(index));
} else if(theGuess.charAt(index) == solution.indexOf(string)) {
hintBuilder.setCharAt(index, "+");
} else {
hintBuilder.setCharAt(index, "*");
}
}
return hintBuilder;
}
Basically, you have to use a 'StringBuilder' because Strings are immutable, meaning that they cannot be altered once they are built.
Also, when comparing two values, use == or === to compare, not =.
UPDATED
I forgot that Strings are immutable in Java, and have updated the code so that it should work.
So i have been trying to make a code that counts the number of words in a string which was pretty easy. I'm running into problems when im trying to make it count the number of unique characters in a string. The program compiles and runs it doesn't display the number of Unique characters. Adding a System.out.println(countOfUniqueChars); below return doesn't work.
Here's the code:
public class Uniquechar{
public static void main(String[] args) {
String s = "Jag vet inte vad jag heter idag";
String[] parts = s.split(" ");
int wordcount = parts.length;
System.out.println("The number of words is" + wordcount);
countUniqueCharacters(s);
}
public static int countUniqueCharacters(String s) {
String lowerCase = s.toLowerCase();
char characters[] = lowerCase.toCharArray();
int countOfUniqueChars = s.length();
for (int i = 0; i < characters.length; i++) {
if (i != lowerCase.indexOf(characters[i])) {
countOfUniqueChars--;
}
}
return countOfUniqueChars;
}
Try this:
s = s.replace(" ", ""); // If you don't want to count space
char[] chars = s.toCharArray();
Set<Character> uniqueChars = new HashSet<>();
for (char c : chars) {
uniqueChars.add(c);
}
System.out.println(c.size());
Just print the method call, it prints the result.
System.out.println(countUniqueCharacters(s));
Adding a System.out.println(countOfUniqueChars); below return doesn't work.
It won't work. Because the code after return statement is unreachable. Perhaps you can do it just before return.
System.out.println(countOfUniqueChars);
return countOfUniqueChars;
You can do System.out.println(countUniqueCharacters(s)); in the main method, to output the return value of your method. After a return, you cannot add more code. I did it for you and the output is 12, so it seems to be that there is also something wrong with your algorithm.
int uniqeCharsCount = countUniqueCharacters(s);
System.out.println("The number of uniqe chars is " + uniqeCharsCount);
Output: 12
Your algorithm:
Actually you are checking every char, if this char is one more time in the string before. But you should also check if the char is anywhere in the string after the current index. You can fix it if you change your if condition to if (i != lowerCase.indexOf(characters[i]) || i != lowerCase.lastIndexOf(characters[i]))
Output of the fixed version: 3 (n, h, r)
I would recommend using a Set to retain only uniques, then count its size, instead of iterating:
public static int countUniqueCharacters(String s) {
String lowerCase = s.toLowerCase();
char characters[] = lowerCase.toCharArray();
Set<Character> uniques = new HashSet<Character>();
for (char c: characters) {
uniques.add(c);
}
return uniques.size();
}
if (i != lowerCase.indexOf(characters[i])) {
countOfUniqueChars--;
}
This is wrong. Your lowerCase string is lowercase, so any uppercase letters in characters[i] will have an index of -1 in lowerCase (will be calculated as a non-unique character). You can fix this by using indexOf(lowerCase.charAt(i));
A good way to count the number of characters would be eliminating repetitions. The ideia is get the first character, then find next occurrences and replace by nothing, once you do that you can count the unique characters.
public static int countUniqueCharacters(String s) {
String lowerCase = s.toLowerCase();
///Get the first char of lowerCase
String firstChar = lowerCase.substring(0,1);
//Take off the first char
String subS = lowerCase.substring(1);
///replace all chars equals to first char
String replacedSubS = subS.replace(firstChar, "");
/// Now, call method again to calculate size
/// of the substring with first char
// replaced by blank char
return 1+countUniqueCharacters(replacedSubS);
}
This method worked for me, take a look. You may do that in two lines, but i thought it's better be detailed here.
Adding a System.out.println(countOfUniqueChars); below return doesn't work.
That is expected behavior because return means that flow of control will be returned from method to place where this method was invoked. This means that code after return will not be executed, so in situation like
return countOfUniqueChars;
System.out.println(countOfUniqueChars);
System.out.println(countOfUniqueChars); would be dead code.
You could try printing value before you return it like
System.out.println(countOfUniqueChars);
return countOfUniqueChars;
or simply print returned value in main method like
int count = countUniqueCharacters(s);
System.out.println(count);
or using this one-liner
System.out.println(countUniqueCharacters(s));
BTW since Java 8 your code can look like
s.toLowerCase().chars().distinct().summaryStatistics().getCount()
or if you want to skip spaces you can add
s.toLowerCase().replace(" ","").chars().distinct().summaryStatistics().getCount()
public static int countUniqueCharacters(String s) {
char [] input=s.toCharArray();
Set<Character> charset=new HashSet<>();
for (int i = 0; i < input.length; i++) {
charset.add(input[i]);
}
return charset.size();
}
I'm having trouble comparing an array that holds a word that's broken up into letters. Here is my code: (it's part of a hangman game)
public static void isGuessCorrect( String guess, String wordInPlay, String[] hangmanScores){
String[] letterGuessedAgainst = wordInPlay.split("");
for (int i = 0;i < letterGuessedAgainst.length; i ++)
System.out.print(letterGuessedAgainst[i]);
System.out.println("Letter guessed against is: "+letterGuessedAgainst[1]);//testing purposes
System.out.println("My guess is: "+guess.charAt(0));//testing purposes
for (int i = 0;i < letterGuessedAgainst.length; i++){
if (letterGuessedAgainst.equals(guess.charAt(0))){//this line isn't working
System.out.println("they're equal");//want it to return this
}//end if
else
System.out.println("they're not");//returns this instead
}//end for
}//end method
guess is a String
holds a letter
wordInPlay is the word that is in play
letterGuessedAgainst is the letter of the word that is being played
hangmanScores is an array that only holds "_", corresponding to the number of letters in the word
Any help would be immensely appreciated! Thanks!
The problem is that letterGuessedAgainst is an array and you are trying to compare a String[] vs char
if (letterGuessedAgainst.equals(guess.charAt(0))){//this line isn't working
First of all, you have to use the index i in the loop
letterGuessedAgainst[i]
Secondly, you need to compare against guess and not guess.charAt(0) since you will not be able to do equals() when comparing String and char
Since you already defined that guess is a String the contains only 1 character then you could do:
if (letterGuessedAgainst[i].equals(guess)) {
Updated your code to start working:
public static void isGuessCorrect(String guess, String wordInPlay, String[] hangmanScores) {
char[] letterGuessedAgainst = wordInPlay.toCharArray(); //Changed to Char Array
for (int i = 0; i < letterGuessedAgainst.length; i++) {
System.out.print(letterGuessedAgainst[i]);
}
System.out.println("Letter guessed against is: " + letterGuessedAgainst[1]);//testing purposes
System.out.println("My guess is: " + guess.charAt(0));//testing purposes
for (int i = 0; i < letterGuessedAgainst.length; i++) {
if (letterGuessedAgainst[i] == guess.charAt(0)) {//Made == since they are all Chars now
//System.out.println("Nice guess! Here are all the "+guess+"'s in the word.");
//System.out.println(hangmanScores);
System.out.println("they're equal");//want it to return this
}//end if
else {
System.out.println("they're not");//returns this instead
}
}//end for
}//end method
There is likely other places that can be improved but this fixes your direct problem.
Rather then splitting into a number of single character String(s), I suggest you use wordInPlay.toCharArray(); then you could iterate that char[] with a For-Each loop (and I believe you wanted to either search the entire String and say the character was found or not; not whether each individual character matches) and your code might look something like
public static void isGuessCorrect(String guess, String wordInPlay,
String[] hangmanScores) {
char[] letterGuessedAgainst = wordInPlay.toCharArray();
char ch = guess.charAt(0);
System.out.println("My guess is: " + ch);
boolean found = false;
for (char letter : letterGuessedAgainst) {
if (letter == ch) {
found = true;
break;
}
}
if (found) {
System.out.printf("%s contains guess %c%n", wordInPlay, ch);
} else {
System.out.printf("%s does not contain guess %c%n", wordInPlay, ch);
}
}
You're comparing a char (which charAt() returns) to a string, which they are not equal. I would suggest using either character arrays, or also using charAt() on letterGuessedAgainst.
Source:
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html
if (guess.length==0) return null; // some kind of error handling
char quessedChar = guess.charAt(0);
for (int i = 0;i < letterGuessedAgainst.length; i++){
if (letterGuessedAgainst.charAt(i) == quessedChar ){
//System.out.println("Nice guess! Here are all the "+guess+"'s in the word.");
//System.out.println(hangmanScores);
System.out.println("they're equal");//want it to return this
}//end if
else
System.out.println("they're not");//returns this instead
}//end for
I would suggest at first place some code to validate your input data. You will fail if you will pass an empty string for guess.
Secondly you are comparing String with a character. Use above code.
Wouldn't you need to do
if (letterGuessedAgainst[i].charAt(0).equals(guess.charAt(0))){
instead of comparing an array to a char
I know I'm missing some things and that's what I really need help with. The code doesn't work in all cases and am looking for help improving/fixing it.
Assignment:
The code I have so far:
public String word(int num, String words)
{
int l = words.indexOf(" ");
int r = words.indexOf(" ", l+1);
for(int i = 3; i <= num; i++){
l = r;
r = words.indexOf(" ", l+1);
//if(i != num)
// l = r;
}
String theword = words.substring(l,r);
return theword;
}
}
As this is clearly homework, I will give you text only.
Your approach may work eventually, but it is laborious and overly complicated, so it's hard to debug and hard to get right.
make use of String's API by using the split() method
after splitting the sentence into an array of word Strings, return the element at num less one (array are indexed starting at zero
check the length of the array first, in case there are less words than num, and take whatever action you think is appropriate in that case
For part 2, a solution in a simple form may be:
create a new blank string for the result
iterate over the characters of the given string adding the character to the front of the result string
make use of String's toUpperCase() method
Since this is homework and you have showed some effort. This is how you can do part 1 of your question. This code is pretty evident.
1) I am returning null if number is greater than the number of words in string as we dont want user to enter 5 when there are only 2 words in a string
2) Splitting the string by space and basically returning the array with the number mentioned by user
There are more conditions which you must figure out such as telling the user to enter a number of the string length since it would not give him any result and taking input from Scanner instead of directy adding input in method.
public static String word(int num, String words)
{
String wordsArr[] = words.split(" ");
if(num <= 0 || num > wordsArr.length) return null;
return (wordsArr[num-1]);
}
the second part of your question must be attempted by you.
Well... not often you see people coming here with homework AND showing effort at the same time so bravo :).
This is example of how you can split the string and return the [x] element from that string
public class SO {
public static void main(String[] args) throws Exception {
int number = 3;
String word = "Hello this is sample code";
SO words = new SO();
words.returnWord(number, word);
}
private void returnWord(int number, String word) throws Exception {
String[] words = word.split("\\s+");
int numberOfWords = words.length;
if(numberOfWords >= number) {
System.out.println(words[number-1]);
} else {
throw new Exception("Not enought words!!!");
}
}
}
Yes it is a working example but do not just copy and paste that for your homework - as simple question from teacher - What is this doing, or how this works and your out :)! So understand the code, and try to modify it in a way that you are familiar what is doing what. Also its worth getting some Java book - and i recommend Head first Java by O'Really <- v.good beginner book!
if you have any questions please do ask!. Note that this answer is not 100% with what the textbook is asking for, so you can modify this code accordingly.
As of part 2. Well what Bohemian said will also do, but there is a lot quicker solution to this.
Look at StringBuilder(); there is a method on it that will be of your interest.
To convert String so all letter are upper case you can use .toUpperCase() method on this reversed string :)
You can try:
public class trial {
public static void main(String[] args)
{
System.out.println(specificword(0, "yours faithfully kyobe"));
System.out.println(reverseString("derrick"));}
public static String specificword(int number, String word){
//split by space
String [] parts = word.split("\\ ");
if(number <= parts.length){
return parts[number];
}
else{
return "null String";
}
}
public static String reverseString(String n){
String c ="";
for(int i = n.length()-1; i>=0; i--){
char m = n.charAt(i);
c = c + m;
}
String m = c.toUpperCase();
return m;
}
}
For the first problem, I'll give you two approaches (1. is recommended):
Use the String.split method to split the words up into an array of words, where each element is a word. Instead of one string containing all of the words, such as "hello my name is Michael", it will create an array of the words, like so [hello, my, name, is, Michael] and that way you can use the array to access the words. Very easy:
public static String word(int num, String words)
{
// split words string into array by the spaces
String[] wordArray = words.split(" "); // or = words.split("\\s+");
// if the number is within the range
if (num > 0 && num <= wordArray.length) {
return wordArray[num - 1]; // return the word from the word array
} else { // the number is not within the range of words
return null;
}
}
Only use this if you cannot use arrays! Loop through the word until you have found enough spaces to match the word you want to find:
public static String word(int num, String words)
{
for (int i = 0; i < words.length(); i++) { // every character in words
if (words.substring(i, i+1).equals(" ")) { // if word is a space
num = num - 1; // you've found the next word, so subtract 1 (number of words left is remaining)
}
if (num == 1) { // found all words
// return this word
int lastIndex = i+1;
while (lastIndex < words.length()) { // until end of words string
if (words.substring(lastIndex, lastIndex+1).equals(" ")) {
break;
}
lastIndex = lastIndex + 1; // not a space so keep moving along the word
}
/*
// or you could use this to find the last index:
int lastIndex = words.indexOf(" ", i + 1); // next space after i+1
if (lastIndex == -1) { // couldn't find another space
lastIndex = words.length(); // so just make it the last letter in words
}*/
if (words.substring(i, i+1).equals(" ")) { // not the first word
return words.substring(i+1, lastIndex);
} else {
return words.substring(i, lastIndex);
}
}
}
return null; // didn't find word
}
As for the second problem, just iterate backwards through the string and add each letter to a new string. You add each letter from the original string to a new string, but just back to front. And you can use String.toUpperCase() to convert the string to upper case. Something like this:
public static String reverse(String str) {
String reversedString = ""; // this will be the reversed string
// for every character started at the END of the string
for (int i = str.length() - 1; i > -1; i--) {
// add it to the reverse string
reversedString += str.substring(i, i+1);
}
return reversedString.toUpperCase(); // return it in upper case
}