Java - Replace a character in a string - java

don't think I haven't searched online for an answer. Why is it giving me outofbounds error?
I have two 6-chars long strings. One is "daniel" and another is "------". User enters a character. Loop goes through the "daniel" string and checking char by char is they match with the user input. If it matches, it should replace the guessed char with the one in "------". So if you input 'a' it should output "-a----" and the loop continues. Next if you enter 'e' it should output "-a--e-" etc. Code gives no compilation error or any warning and also makes perfect sense. I tried substring and replace but this is simpler and shorter. I tried debugging it but it gives no useful info. I don't know why is it returning outofbounds error.
package hello.world;
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
String word="daniel";
StringBuilder guess2 = new StringBuilder("------");
char guess;
System.out.println("**********************");
System.out.println("* Welcome to Hangman *");
System.out.println("**********************");
for (int i=0;i<10;i++) {
System.out.print("Enter a letter: ");
guess=in.nextLine().charAt(0);
for (int j=0;i<word.length();j++) {
if (guess==word.charAt(j)) {
guess2.setCharAt(word.charAt(j), guess);
System.out.print(guess2);
}
}
}
}
}
Output:
**********************
* Welcome to Hangman *
**********************
Enter a letter: a
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 97
at java.lang.AbstractStringBuilder.setCharAt(AbstractStringBuilder.java:380)
at java.lang.StringBuilder.setCharAt(StringBuilder.java:76)
at hello.world.HelloWorld.main(HelloWorld.java:22)
Java Result: 1
BUILD SUCCESSFUL (total time: 2 seconds)

Replace
guess2.setCharAt(word.charAt(j), guess);
with
guess2.setCharAt(j, guess);
The first parameter is the index of the character to replace in the StringBuilder, not the character itself.
Also, there seems to be a typo in the for loop using i instead of j.
for (int j=0;i<word.length();j++) {

String.length() returns the length of string starting from 1 and not from 0. So whenever you use String.length() always use less than (<) symbol.

Instead of using the String builder you can just replace everything using regex + replaceAll method
for (int i=0;i<10;i++) {
System.out.print("Enter a letter: ");
guess=in.nextLine().charAt(0);
word = word.replaceAll("[^"+ guess +"]", "-");
System.out.println(word);
}
result:
Enter a letter: a
-a----

Related

How to Find the word that comes after a specified word in java String

My program has a String inputted Eg. hello i am john who are you oh so i see you are also john i am happy
my program then has a keyword inputted Eg. i (the program doesn't like capitals or punctuation yet)
then it reads the initial String and finds all the times it mentions the keyword + the word after the keyword, Eg. i am, i see, i am.
with this is finds the most common occurrence and outputs that second word as the new keyword and repeats. this will produce
i am john/happy (when it comes to an equal occurrence of a second word it stops (it is meant to))
What i want to know is how i find the word after the keyword.
package main;
import java.util.Scanner;
public class DeepWriterMain {
public static void main(String[] args) {
String next;
Scanner scanner = new Scanner(System.in);
System.out.println("text:");
String input = scanner.nextLine();
System.out.println("starting word:");
String start = scanner.nextLine();
input.toLowerCase();
start.toLowerCase();
if (input.contains(start)) {
System.out.println("Loading... (this is where i find the most used word after the 'start' variable)");
next = input.substring(5, 8);
System.out.println(next);
}else {
System.out.println("System has run into a problem");
}
}
}
If you use split to split all your words into an array, you can iterate through the array looking for the keyword, and if it is not the last in the array, you can print the next word
String arr [] = line.split(" ");
for (int i = 0; i < arr.length -1; i++) {
if (arr[i].equalsIgnoreCase(keyword)) {
sop(arr[i] + " " arr[i + 1]);
}
if it is not the last in the array, iterate only to length - 1
The String class includes a method called public int indexOf(String str). You could use this as follows:
int nIndex = input.indexOf(start) + start.length()
You then only need to check if nIndex == -1 in the case that start is not in the input string. Otherwise, it gets you the position of the first character of the word that follows. Using the same indexOf method to find the next space provides the end index.
This would allow you to avoid a linear search through the input, although the indexOf method probably does one anyway.

Counting the number of words beginning with a CAPITAL VOWEL using a Recursive function

This is my code below which counts and displays the number of words beginning with a capital vowel:
The function count() is a recursive function which counts the number of such words.
import java.util.*;
class Check
{
String str; int w;
StringTokenizer S;
void InputString()
{
Scanner sc=new Scanner (System.in);
System.out.println("Enter a String:");
str=sc.nextLine();
}
void counter(int nWord)
{
if(nWord<=S.countTokens())
{
String word=S.nextToken();
char first=word.charAt(0);
if(first=='A' || first=='E' || first=='I' || first=='O' || first=='U')
//Checking if the word begins with a CAPITAL VOWEL.
{
w++;
}
counter(nWord+1);
}
}
void display()
{
S=new StringTokenizer(str);
counter(1);
System.out.println("Given String: "+str);
System.out.println("Number of words beginning with capital vowels = "+w);
}
void main()
{
InputString();
display();
}
}
For input: "Java Is An Object Oriented Programming Language."
Output: number of such words=3
But clearly, there are 4 such words in the given String. I would like to know where I made a mistake.
Thanks!
Javadoc says about StringTokenizer.countTokens():
Calculates the number of times that this tokenizer's nextToken method
can be called before it generates an exception. The current position
is not advanced.
In other words, after each call of nextToken, countTokens will return a lower number.
This causes your counter to be called not as often as you expect.
Instead of if (nWord<=S.countTokens()), try if (S.countTokens() > 0).
This is because S.countTokens() return remaining number of tokens in the tokenizer. Initially, there are 7 tokens in "Java Is An Object Oriented Programming Language". When you call S.nextToken(), it removes "Java" from the list and upon next call of S.countTokens(), we get 6 (instead of 7, since Java is no more in the list of tokens).
The loop ends when you have read 4 tokens, and there are only 3 more tokens left. At this stage, nWord = 4 but S.countTokens() = 3, so the recursion stops here and you don't get to the words "Oriented Programming Language" at all.
To fix this, count the number of tokens initially in display() function itself and store it in a variable nTokens. Then the checking condition becomes:
if(nWord <= nTokens)
The full code would then look like:
import java.util.*;
class Check
{
String str; int w;
int nTokens; //this variable stores number of tokens
StringTokenizer S;
void InputString()
{
Scanner sc=new Scanner (System.in);
System.out.println("Enter a String:");
str=sc.nextLine();
}
void counter(int nWord)
{
if(nWord<=nTokens) //the changed condition
{
String word=S.nextToken();
char first=word.charAt(0);
if(first=='A' || first=='E' || first=='I' || first=='O' || first=='U')
//Checking if the word begins with a CAPITAL VOWEL.
{
w++;
}
counter(nWord+1);
}
}
void display()
{
S=new StringTokenizer(str);
nTokens = S.countTokens();
counter(1);
System.out.println("Given String: "+str);
System.out.println("Number of words beginning with capital vowels = "+w);
}
void main()
{
InputString();
display();
}
}
This code correctly outputs 4 as expected.
The class does not evaluate all the words of the input, that is why the number is off.
When you print out the parameter nWord and the return value of S.countTokens() in count(), you will see that while nWord increases, the return value of countTokens() decreases with each call until it is smaller than nWord, which will stop the recursion before all the tokens are looked at.
The countTokens() function returns the number of remaining tokens, not the total number of tokens, so it decreases while the tokens are consumed by nextToken().
Enter a String:
Java Is An Object Oriented Programming Language.
nWord=1 countTokens=7
Java
nWord=2 countTokens=6
Is
nWord=3 countTokens=5
An
nWord=4 countTokens=4
Object
nWord=5 countTokens=3
Given String: Java Is An Object Oriented Programming Language.
Number of words beginning with capital vowels = 3
You could just use the preferred function hasMoreTokens() of the StringTokenizer to see if there are more tokens to process and then the result will be correct:
...
if(S.hasMoreTokens())
{
String word=S.nextToken();
...
Enter a String:
Java Is An Object Oriented Programming Language.
Given String: Java Is An Object Oriented Programming Language.
Number of words beginning with capital vowels = 4

Getting multiple inputs from user with char and integers Java

I'm trying to allow the user to put in multiple inputs from the user that contain a char and integers.
Something like this as input: A 26 16 34 9
and output each int added to an array.
I was thinking I could have the first input as a character and then read the rest as a string which then I separate and put into an array.
I'm not new to coding but new to java. I've been doing c++ so the syntax is a bit different.
This is what I have so far, I haven't set up my array yet for the integers.
import java.util.Scanner;
public class Program0 {
public static void main(String[] args) {
int firstNumber;
Scanner reader = new Scanner(System.in);
System.out.println("'A' to enter a number. 'Q' to quit");
int n = reader.nextInt();
if (n=='A') {
//if array is full System.out.println("The list is full!");
//else
System.out.println("Integer " + " " + "has been added to the list");
}
else if (n=='Q') {
System.out.println("List of integers: ");
System.out.println("Average of all integers in the list: ");
}
else{
System.out.println("Invalid Action");
}
reader.close();
}
}
Could you specify better how should your input be given? From your question, if I understand well, the user simply type "A" followed by a list of numbers separated by a space. So I would simply read the next line, split it in words (separated by a space) and check if the first word is the letter "A". Here it goes:
import java.util.Scanner;
public class Program0 {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.println("'A' to enter a number. 'Q' to quit");
String line = reader.nextLine();
String[] words = line.split(" ");
if (words.length > 0 && words[0].equals("A")) {
//if array is full System.out.println("The list is full!");
// => I don't understand this part
//else
for(int i = 1; i<words.length; i++){
int integer = Integer.parseInt(words[i]);
System.out.println("Integer " + integer + " has been added to the list");
//do your stuff here
}
}
else if (words.length > 0 && words[0].equals("Q")) {
System.out.println("List of integers: ");
System.out.println("Average of all integers in the list: ");
}
else{
System.out.println("Invalid Action");
}
reader.close();
}
}
Note that in your solution, you read the next int from your scanner and then try to compare it with the character 'A'. This will not work because A is not an int. If you really want to get the first character from your scanner, you could do:
String line = reader.nextLine();
if(line.length() > 0){
char firstChar = line.charAt(0);
//do your stuff here
}
A character is not an int. You cannot read an int to expect something like 'A'. You can read a String and take its first character though. Scanner doesn't offer a convenient method to read the next String and expect it to be only one-character long. You'd need to handle that yourself.
But considering you don't know in advance how many numbers there will be to read, your solution to read the entire line and interpret it entirely, is the better one. That means you can't use nextInt() nor nextDouble() nor next() nor nextWhateverElse().
You need nextLine(), and it will give you the entire line as a String.
Then you can split() the result, and check if the first is one-char-long. Then you can parse all the others as int.
I don't immediately recall how to write this in Java – it's been a bit of a while – but what I'd do is to first separate the string by spaces, then attempt to do ParseInt on each piece.
If the string isn't a valid integer, this method will throw an exception, which you can catch. So:
If you make it to the next statement, an exception didn't happen, so the value is an integer.
If, instead, you find yourself in the exception-handler (having caught [only ...] the expected kind of exception, the value is a string.
Of course, don't "catch" any exception-type other than the NumberFormatException that you're expecting.
By the way, it is perfectly routine to use exceptions in this way. Let Java's runtime engine be the authority as to whether it's an integer or not.

Counting a String's Lowercase Letters

I was looking around forums and found a helpful code on how to count lowercase letters in an inputted string. Thing is, after testing it, I saw it only counts lowercase letters within the first word typed. So, for example, if I type: HeRE the counter will say I've typed in 1 lowercase letter (which is correct), but if I type in: HeRE i am the counter will still only say 1 instead of 4. It's only counting the lowercase letters in the first word. How do I get it to count lowercase letters in my entire string?
Code thus far:
import java.util.Scanner;
public class countingLowerCaseStrings {
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
System.out.println("Enter your string: ");
String input = scanner.next();
int LowerCaseLetterCounter = 0;
for (char ch : input.toCharArray()) {
if (Character.isLowerCase(ch)) {
LowerCaseLetterCounter++;
}
}
System.out.println ("Number of lower case letters in this string is: " +
LowerCaseLetterCounter);
}
}
Thanks a bunch for the help!
scanner.next(); reads the first available word, not the entire line.
So if you input "HeRE i am" it will just read "HeRE".
Change it to scanner.nextLine():
System.out.println("Enter your string: ");
String input = scanner.nextLine();
DEMO - look at stdin and stdout panels.
As a matter of interest, Java 8 provides a fairly streamlined way of achieving the same thing:
scanner.nextLine().chars().filter(Character::isLowerCase).count()

Java String output limiting range of String to Alphabet

I'm currently doing an exercise(not homework before anyone gives out) and I am stuck in the final part of the question.
The question is:
Write a program which will input a String from the keyboard, output the number of
seperate words, where a word is one or more characters seperated by spaces. Your
program should only count words as groups of characters in the rang A..Z and a..z
I can do the first part no problem as you can see by my code:
import java.util.Scanner;
public class Exercise10 {
public static void main(String[] args) {
String input;
int counter = 0;
Scanner keyboard = new Scanner(System.in);
System.out.println("Please enter your text: ");
input = keyboard.nextLine();
for(int i = 0; i < input.length(); i++){
if(input.charAt(i) == ' '){
counter++;
}
}
System.out.println(counter + 1);
keyboard.close();
}
}
However the part that is confusing me is this:
Your program should only count words as groups of characters in the rang A..Z and
a..z
What should I do in this instance?
I won't give you a full answer but here are two hints.
Instead of counting spaces look at splitting the string and looping through each element from the split:
Documentation
Once you have the String split and can iterate through the elements, iterate through each character in each element to check if it is alphabetic:
Hint
I believe it should not consider separate punctuation characters as words. So the phrase one, two, three ! would have 3 words, even if ! is separated by space.
Split the string on spaces. For every token, check the characters; if at least one of them is in range a..z or A..Z, increment counter and get to the next token.

Categories