User string input. Counting characters - java

My code works except I have to make it pass some Junit test. It passes all but one. It passes when the character enters nothing, enters upper case, lower case, or a mix of the two, and it works when the enter Hello World!
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] textArray = new int[26];
System.out.print("Enter text: ");
readText(input, textArray);
}
public static void readText(Scanner input, int[]text){
char letter = 0;
if (input.hasNext() == false) {
System.out.println();
}
else {
while (input.hasNext()) {
String a = input.nextLine();
for (int i = 0; i < a.length(); i++) {
letter = a.charAt(i);
if (letter >= 'A' && letter <= 'Z') {
text[letter-65] = (text[letter-65]) + 1;
}
else if (letter >= 'a' && letter <= 'z') {
text[(letter - 32) - 65] = (text[(letter - 32) - 65]) + 1;
}
else if (letter == ' ') {
System.out.print("");
}
else {
System.out.print("");
}
}
}
}
String[] alphabet = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
for (int y = 0; y < text.length; y++) {
if (text[y] > 0) {
System.out.println(alphabet[y] + ": " + text[y]);
}
}
}
The Junit tests this input: 1 2 3%n! ? >%n:) !!%n
The expected output is
Enter text:
//empty line here
But instead the output from my code is
Enter text: //with no line after
I'm not sure how to get the extra line after without ruining my other junit tests. I tried one way and it worked but then my Hello World didn't work properly.
And example of when its working:
When I hit run the console will say
Enter text:
I have a Scanner input so the user will enter some words and it will look like this in console
Enter text: sOme wordS
Then it will count the number of times each letter was used and print that to console like this
Enter text: sOme wordS
D: 1
E: 1
M: 1
O: 2
R: 1
S: 2
W: 1
If I don't enter anything when asked and just hit the enter key the output is
Enter text:
//empty line here
But when I enter
Enter text: 1 2 3
? ! >
:) !!
The output doesn't add an extra line at the end.

Try using System.out.println("Enter text: "); instead of System.out.print("Enter text: ");
Update: After getting clarified your requirement I propose to use the following code.
public static void readText(Scanner input, int[]text){
char letter = 0;
while (input.hasNext()) {
String a = input.nextLine();
for (int i = 0; i < a.length(); i++) {
letter = a.charAt(i);
if (letter >= 'A' && letter <= 'Z') {
text[letter-65] = (text[letter-65]) + 1;
}
else if (letter >= 'a' && letter <= 'z') {
text[(letter - 32) - 65] = (text[(letter - 32) - 65]) + 1;
}
else if (letter == ' ') {
System.out.print("");
}
else {
System.out.print("");
}
}
}
String[] alphabet = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
boolean emptyOutput = true;
for (int y = 0; y < text.length; y++) {
if (text[y] > 0) {
System.out.println(alphabet[y] + ": " + text[y]);
emptyOutput = false;
}
}
if (emptyOutput) {
System.out.println();
}
}

Related

How do I edit this coding to show the characters with frequency 0. eg: a=0. Because now it only shows the characters which has freq > 0 only

Write a program that will read a line of text String and display all the letters that occur in the text, one per line and in alphabetical order, along with the number of times each letter occurs in the text.
For this purpose, you must use an array of type int of length 26, so that the element at index 0 contains the number of a’s, the element at index 1 contains the number of b’s, and so forth.
Allow both uppercase and lowercase letters as input, but treat uppercase and lowercase versions of the same letter as being equal.
Hint: Use the method chatAt(int index) in the String class to get the individual character in a string at the specified index.
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] letters = new int[26];
char choice;
while (true) {
// taking user input
System.out.println("Please enter text ending with period:");
String text = sc.nextLine();
// converting it lowercase
text = getActualText(text).toLowerCase();
char c = 'a';
for (int i = 0; i < letters.length; i++)
// increasing character by 1
letters[i] = countLetters(text, c++);
System.out.println("\nThe frequency of the letters");
c = 'a';
for (int i = 0; i < letters.length; i++) {
// showing only those letters whose frequnecy is greater than 0
if (letters[i] != 0)
System.out.println(c + ": " + letters[i]);
c++;
}
System.out.print("Would you like to try another text?(Y/N) ");
choice = sc.nextLine().charAt(0);
if (choice == 'n' || choice == 'N')
break;
}
}
private static int countLetters(String text, char c) {
int count = 0;
for (int i = 0; i < text.length(); i++)
// counting the frequency
if (text.charAt(i) == c)
count++;
return count;
}
/**
* This method will extract the first sentence from a text ending with full stop(.)
*/
private static String getActualText(String text) {
String newText = "";
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == '.')
// breaking out of the loop if the full stop is found
break;
// adding it to the text
newText += text.charAt(i) + "";
}
return newText;
}
}
Try to change existing condition to below new condition:
Existing Condition: (Allowing frequencies which are not equal to 0):
if(letters[i] != 0) {//showing only those letters whose frequency is greater than 0
New Condition: (Allowing frequencies which are greater than or equal to 0):
if(letters[i] >= 0) {
It's enough to go through the text one time and count the occurrence of each letter. And then just show only letters with count >0.
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
do {
System.out.print("\nEnter the text: ");
String str = scan.nextLine();
print(histogram(str));
} while (shouldContinue(scan));
}
private static int[] histogram(String str) {
int[] letters = new int[26];
for (int i = 0; i < str.length(); i++)
if (Character.isLetter(str.charAt(i)))
letters[Character.toLowerCase(str.charAt(i)) - 'a']++;
return letters;
}
private static void print(int[] letters) {
System.out.println("The frequency of the letters:");
for (int i = 0; i < letters.length; i++)
if (letters[i] > 0)
System.out.println((char)('a' + i) + ": " + letters[i]);
}
private static boolean shouldContinue(Scanner scan) {
while (true) {
System.out.print("Would you like to try another text (Y/N)? ");
String str = scan.nextLine();
if (str.length() != 1)
continue;
if ("Y".equalsIgnoreCase(str))
return true;
if ("N".equalsIgnoreCase(str))
return false;
}
}

How can I count with indexOf in Java?

I want to replace from String and print how many times it replaced.
for examples)
Input : aabba
from : aa
to : bb
ddbba
replaced : 1
Input : AAccaabbaaaaatt
from : aa
to : bb
ddccddbbddddatt
replaced : 4
I have a problem here:
for (int i = 0; i < input.length(); i++) {
if (inputL.indexOf(curStrL, i) > -1) {
cnt++;
i = (inputL.indexOf(curStrL, i))+1; // this part!
} else
continue;
} // for
My teacher said just use .indexOf and .replace, and .toLowerCase.
She gave some examples and they always replace two letters to two letters.
That's the reason why I put '+1' to find another letter.
If I remove that '+1', it counts 'aaa' twice.(aa a and a aa. And it replaced to 'dda', so it's wrong.)
But this time when I replace only one letter(ex.a), it counts less numbers than actually it has to be.(ex.'aaa' counts just two times.)
With the examples from teacher, it works well cuz all of them replace two letters.
But I want to improve this.
Here is all of my code:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while (true) {
System.out.print("Input : ");
String input = scan.next();
System.out.print("from : ");
String curStr = scan.next();
System.out.print("to : ");
String chStr = scan.next();
String inputL = input.toLowerCase();
String curStrL = curStr.toLowerCase();
String chStrL = chStr.toLowerCase();
String output = inputL.replace(curStrL, chStrL);
int cnt = 0;
if (inputL.indexOf(curStrL) == -1) {
System.out.println("Do it again");
} else
System.out.println(output);
for (int i = 0; i < input.length(); i++) {
if (inputL.indexOf(curStrL, i) > -1) {
cnt++;
i = (inputL.indexOf(curStrL, i))+1;
// *** to make the code find from the next letter! ***
} else
continue;
} // for
if (cnt > 0)
System.out.println("replaced : " + cnt);
else
{System.out.println("can't replace. Do it again");
break;}
System.out.println("----------------");
} // while
} // main
Just increase the counter variable of your loop with the lenght of the string to be replaced.
for (int i = 0; i < input.length(); i++) {
if (inputL.indexOf(curStrL, i) > -1) {
cnt++;
i = (inputL.indexOf(curStrL, i)); // EDIT by Shraft
i = i + curStr.length() - 1; // EDIT
// *** to make the code find from the next letter! ***
} else
continue;
} // for

How to break from a loop after finding a word

I am trying to create a Hangman and I have 2 problems.
1) The first problem is when the user finds the word, the loop does not stop.
2) I have a variable attempts which allows to know the number of attempts. Even if the user finds the letter, the number of attempts decrease.
The word to find is no
Here is a demonstration:
1) I enter the letter n
You have 5 attempts.
--
Enter your letter : n
2) I enter the letter o
The letter is good.
You have 4 attempts.
n-
Enter your letter : o
3) Normally the loop should stop.
The letter is good.
You have 3 attempts.
no
Enter your letter :
If you have an idea thank you in advance.
Scanner input = new Scanner(System.in);
char letter = 0;
String[] words = {/*"yes",*/ "no"};
String word_random = words[(int) (Math.random() * words.length)];
boolean[] word_found = new boolean[word_random.length()];
int attempts = 5;
while(attempts > 0){
System.out.println("You have " + attempts + " attempts.");
for(int i=0; i<word_random.length(); i++) {
if ( word_found[i] ) {
System.out.print(word_random.charAt(i));
}
else {
System.out.print('-');
}
}
System.out.println("");
System.out.print("Enter your letter : ");
letter = input.next().charAt(0);
for(int i=0; i<word_random.length();i++){
if(word_random.charAt(i) == letter){
System.out.println("The letter is good. ");
word_found[i] = true;
}
}
attempts--;
}
}
}
You are just missing a checking loop or method. Check the solution below.
Scanner input = new Scanner(System.in);
char letter = 0;
String[] words = {/*"yes",*/ "no"};
String word_random = words[(int) (Math.random() * words.length)];
boolean[] word_found = new boolean[word_random.length()];
int attempts = 5;
while(attempts > 0){
System.out.println("You have " + attempts + " attempts.");
for(int i=0; i<word_random.length(); i++) {
if ( word_found[i] ) {
System.out.print(word_random.charAt(i));
}
else {
System.out.print('-');
}
}
System.out.println("");
System.out.print("Enter your letter : ");
letter = input.next().charAt(0);
for(int i=0; i<word_random.length();i++){
if(word_random.charAt(i) == letter){
System.out.println("The letter is good. ");
word_found[i] = true;
}
}
boolean done = true;
for(boolean b : word_found)
done = done && b;
if(done) break;
else attempts--;
}
I will follow to your solution, not suggest a better one.
Ad 1. Add a check if the array word found contains only true after your first for cycle and if there are only true values in the array, print "you won" and set attempts to 0
Ad 2. Move attempts-- to the else case of your first for cycle OR add attempts++ in the true case of your first for cycle
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
char letter = 0;
String[] words = { /* "yes", */ "no" };
String word_random = words[(int) (Math.random() * words.length)];
boolean[] word_found = new boolean[word_random.length()];
int attempts = 5;
while (attempts > 0) {
System.out.println("You have " + attempts + " attempts.");
for (int i = 0; i < word_random.length(); i++) {
if (word_found[i]) {
System.out.print(word_random.charAt(i));
} else {
System.out.print('-');
}
}
System.out.println("");
System.out.print("Enter your letter : ");
letter = input.next().charAt(0);
boolean match = false;
for (int i = 0; i < word_random.length(); i++) {
if (word_random.charAt(i) == letter) {
System.out.println("The letter is good. ");
word_found[i] = true;
match = true;
if (i == word_found.length - 1) {
System.out.println("THE END: attempts: " + attempts);
return;
}
}
}
if (!match) {
attempts--;
}
}
System.out.println("THE END");
}
I suggest you to modify the last part of your code like I did, and it should work.

Write a program that prompts the user to enter a string, then displays the total number of characters and total number of lower case characters

I am a beginner so please help me! so the goal is to write a program in simple java that will ask someone to enter a string, then prints the total characters, as well as the total lower case characters, here is what I have so far...
import java.util.Scanner;
public class test2 {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.println("Enter a string");
String s = input.nextLine;
String lower = "";
String total = "";
for (int i = 0; i < s.length(); i++) {
char thisChar = s.charAt(i);
} if (thisChar >= 97 && thisChar <= 122) {
lower += thisChar;
}
System.out.println("Total amount of characters: " + s.length() + " - " + s);
System.out.println("Lower case letters: " + lower.length() + " - " + lower);
}
}
Try this:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter a string");
String s = input.nextLine();// methods should be called with () even if have no argument
String lower = "";
String total = "";
for (int i = 0; i < s.length(); i++) {
char thisChar = s.charAt(i);
// you can replace with : if (Character.isLowerCase(thisChar))
if (thisChar >= 97 && thisChar <= 122) {
lower += thisChar;
}
}//close the for loop here
System.out.println("Total amount of characters: " + s.length() + " - " + s);
System.out.println("Lower case letters: " + lower.length() + " - " + lower);
}
What is the question?
It looks like you closed your "for" loop earlier than you should
Scanner.nextLine() is a method, not a variable so you should put the () after it. Look at your String s = input.nextLine; and change it to String s = input.nextLine();
Braces
for (int i = 0; i < s.length(); i++) {
char thisChar = s.charAt(i);
} if (thisChar >= 97 && thisChar <= 122) {
lower += thisChar;
}
as you can see, the first } closes the for so it means: thisCar will not be anymore visible and you cannot use it outside! Change it to
for (int i = 0; i < s.length(); i++) {
char thisChar = s.charAt(i);
if (thisChar >= 97 && thisChar <= 122) {
lower += thisChar;
}
}
Use 'a' and 'z' as range. So the if will be
if (thisChar >= 'a' && thisChar <= 'z') {
You don't need a total variable.
Use a StringBuilder if you need to create a string, you will avoid the creation of useless temporary strings.
Logic
You need to only count the number of lowercase letters or show too? If the former, just use a integer variable and increment it everytime instead of put everything inside lower String.
int lower = 0;
for (int i = 0; i < s.length(); i++) {
char thisChar = s.charAt(i);
if (thisChar >= 'a' && thisChar <= 'z') {
lower ++;
}
}
nextLine is a method so it should be followed by parenthesis. nextLine()
If you compare a char with char, the compiler will automatically compare them using their ASCII, so you don't have to know the ASCII of any letter, just insert the char as it is.
The if statement should be in the for loop, it makes sense ;)
Check this code for better understanding.
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter a string");
String s = input.nextLine();
String lower = "";
for (int i = 0; i < s.length(); i++) {
char thisChar = s.charAt(i);
if (thisChar >= 'a' && thisChar <= 'z') {
lower += thisChar;
}
}
System.out.println("Total amount of characters: " + s.length() + " - " + s);
System.out.println("Lower case letters: " + lower.length() + " - "+ lower);
}

Java phrase guessing game

Wondering how to exit if total phrase is guessed and why my vowels, spaces and consonants are not counting? Most of progam runs great just cant figure out how to exit without saying "n" to question. I am returning values for counters, don't understand?
import java.util.Scanner;
public class Prog09
{
public static void main(String[] args)
{
Scanner stdIn = new Scanner(System.in);
// Initializes all string variables
String sPhrase;
String answer;
// Initializes all int variables
int vowels = 0;
int consonants = 0;
int spaces = 0;
// Initializes all char variables
char cGuess = 0;
char vGuess = 0;
boolean valid = false;
// Asks user to enter if they want to play
System.out.print("Do you want to play a game? [y/n] ");
answer = stdIn.nextLine();
// Asks user to enter the phrase
System.out.print("Please enter the phrase to guess at : ");
sPhrase = stdIn.nextLine();
// Checks if user wants to play
while (answer.equalsIgnoreCase("y"))
{
char[] phrase = new char[sPhrase.length()];
char[] tmpArr = new char[sPhrase.length()];
for(int i = 0; i < sPhrase.length();i++)
{
tmpArr[i] = sPhrase.charAt(i);
phrase[i] = sPhrase.charAt(i);
}
// Runs methods and main body of program
initTemplateArray(sPhrase, tmpArr, spaces);
printHeader();
printTemplateArray(tmpArr);
System.out.println("");
System.out.println("");
while (answer.equalsIgnoreCase("y"))
{
//getConsonant(stdIn, cGuess);
cGuess = getConsonant(stdIn, cGuess);
vGuess = getVowel(stdIn, vGuess);
isVowel(vGuess, valid);
updateTemplateArray(tmpArr, sPhrase, cGuess, vGuess, consonants, vowels);
printHeader();
printTemplateArray(tmpArr);
System.out.println("");
System.out.println("");
stdIn.nextLine();
System.out.print("Do you want to try again? [y/n]: ");
answer = stdIn.next();
vGuess = 0;
cGuess = 0;
}
}
// Prints results
System.out.println("The common phrase contained: Spaces: " + spaces + " Consonants: " + consonants + " Vowels: " + vowels);
stdIn.close();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Methods for program
public static int initTemplateArray(String sPhrase, char [] tmpArr, int spaces)
{
for (int i = 0; i < sPhrase.length(); i++)
{
if (sPhrase.charAt(i) == ' ')
{
spaces++;
tmpArr[i] = ' ';
}
if (!(sPhrase.charAt(i) == ' '))
{
tmpArr[i] = '?';
}
}
return spaces;
}
public static void printTemplateArray(char [] tmpArr)
{
for (int i = 0; i < tmpArr.length; i++)
{
System.out.print(tmpArr[i]);
}
System.out.println();
}
public static boolean isVowel(char c, boolean valid)
{
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
{
return valid = true;
}
else
{
return valid = false;
}
}
public static char getConsonant(Scanner stdIn, char cGuess)
{
while(cGuess == 'a' || cGuess == 'e' || cGuess == 'i' || cGuess == 'o' || cGuess == 'u'|| cGuess == 0)
{
System.out.print("Enter a lowercase consonant guess : ");
String myGuess = stdIn.next();
cGuess = myGuess.charAt(0);
}
return cGuess;
}
public static char getVowel(Scanner stdIn, char vGuess)
{
while(!(vGuess == 'a' || vGuess == 'e' || vGuess == 'i' || vGuess == 'o' || vGuess == 'u'))
{
System.out.print("Enter a lowercase vowel guess : ");
String newGuess = stdIn.next();
vGuess = newGuess.charAt(0);
}
return vGuess;
}
public static int updateTemplateArray(char [] tmpArr, String sPhrase, char cGuess, char vGuess, int consonants, int vowels)
{
vowels = 0;
consonants = 0;
for (int i = 0; i < tmpArr.length; i++)
{
if (cGuess == sPhrase.charAt(i))
{
tmpArr[i] = sPhrase.charAt(i);
consonants++;
}
if (vGuess == sPhrase.charAt(i))
{
tmpArr[i] = sPhrase.charAt(i);
vowels++;
}
}
return consonants & vowels;
}
public static void printHeader()
{
System.out.println("");
System.out.println(" Common Phrase");
System.out.println("---------------");
}
}
Java passes Ints by value instead of by reference, this means that updateTemplateArray doesn't modify the values of main's vowels, consonants or spaces. To fix this you could:
Make these variables global by definining them outside the scope of the main method. You would have to change the name of the parameters in the updateTemplateArray method to prevent shadowing.
Break updateTemplateArray into separate functions to count each of the vowels, consonants or spaces, and have them return the count of each. You would then call something like: vowels = countVowels(sPhrase); to populate the variables.
With the current setup, it will exit whenever answer stops being equal to 'y' Changing the value of answer at any time will exit the loop.

Categories

Resources