I made this simple GUI program that counts the vowels and consonants of a particular sequence of characters. The counter is okay, but I'm having a problem with the if-else statement where I had to display a message when that character is neither a vowel nor consonant... Here's the code:
//I initialized these variables:
public static int vowels = 0, consonants = 0, charac = 0;
public static String outputStr;
public static String conso = "bcdfghjklmnpqrstvwxyz";
public static String vow = "aeiou";
//Here's the code for my "count" button
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String userInput = jTextField1.getText();
userInput = userInput.toUpperCase();
conso = conso.toUpperCase();
vow = vow.toUpperCase();
String wordInput[] = userInput.split("");
vowels = 0;
consonants = 0;
charac = 0;
for(int i=0; i<wordInput.length; i++) {
for(int j=0; j<5; j++) {
char v = vow.charAt(j);
String VL = Character.toString(v);
if(VL.equals(wordInput[i])) {
vowels ++;
charac = 0;}
else {
charac += 1; }
}
for(int h=0; h<21; h++) {
char c = conso.charAt(h);
String CL = Character.toString(c);
if(CL.equals(wordInput[i])) {
consonants ++;
charac = 0; }
else {
charac += 1; }
}
}
String totalVow = Integer.toString(vowels);
String totalCons = Integer.toString(consonants);
jLabel5.setText(totalVow);
jLabel6.setText(totalCons);
//here's the if-else statement:
if (charac == 0) {
jLabel7.setText(" ");
}
else if (charac >= 1) {
jLabel7.setText("The sequence contains invalid characters.");
}
if (userInput.isEmpty()) {
jLabel7.setText("No input.");
}
}
Here's what it looks like:
I entered a "sequence" of characters that does not have any special characters or digits. But it still displays the message wherein it has other characters other than the vowels and consonants. Is there something wrong with the if-else statement? Thanks for the help :)
The problem is in the inner for loop. Every character is tested with each of 5 different vowels, so surely it will fail to match at least 4 of them, and charac will be incremented
for(int j=0; j<5; j++) {
char v = vow.charAt(j);
String VL = Character.toString(v);
if(VL.equals(wordInput[i])) {
vowels ++;
charac = 0;}
else {
charac += 1;
}
}
Instead, you can use the String.contains() method in place of the inner loop.
You put irrelevant code in your loop. Your loop should like:
for(int i=0; i<wordInput.length; i++) {
char ch=wordInput.charAt(i);
if(Character.isLetter(ch)){
if(isVowel(ch)){// make a method which return true if char is vowel.
vowel++;
}
else{
consonent++;
}
}
}
Your logic for counting invalid characters if wrong. What you do is: you increase the counter each time the character is not the character you just tested, that is, for each character in your input, the charac variable is increased 25 times! But then, the next time the character matches the currently tested vowel or consonant, you reset the charac variable to 0!
Instead of using two for loops to check for each of your vowels and consonants individually, you can use builtin String methods to check whether the current character is one of the vowels or consonants, e.g., indexOf. This way, the checks are reduced to a single if-statement each, making it much easier to have the "else" case for when it's neither a vowel nor a consonant.
for (int i = 0; i < userInput.length(); i++) {
char c = userInput.charAt(i);
if (vow.indexOf(c) != -1) {
vowels++;
} else if (conso.indexOf(c) != -1) {
consonants++;
} else {
charac++; // invalid character
}
}
Also, note that instead of splitting the string to an array of strings you can also use the charAt method.
You're adding to charac in both loops: one that looks up the consonants and the one that looks up the vowels. You'd want to use an if/else-if/else here, where only if a character is not a consonant or a vowel you add to charac.
Also, take a look Guava utilities. For instance, this is how you get all vowels and all consonants:
String vowels = "aeiou";
String consonants = "bcdfghjklmnpqrstvwxz";
String input = "mary had a little lamb";
String allVowels = CharMatcher.anyOf(vowels).retainFrom(input);
String allConsonants = CharMatcher.anyOf(consonants).retainFrom(input);
Related
I'm a programming newbie and I am doing a coderbyte exercise that says "
Replace every letter in the string with the letter following it in the alphabet (ie. c becomes d, z becomes a)"
i'm thinking of the following methods:
declare a string called "abcdefghijklmnopqrstuvxyz" and compare each string's char index position with the alphabet's index position, and then just bring the alphabet char that is located at the i+1 index location. But I don't know how it would work from z to a.
I've seen some techniques using ASCII values for every char but I've never done that before and not sure how it works
convert the given string into a char[] array, but then I'm not sure how I would tell the system to get me the next alphabet char
What would be the easiest way to do this?
EDIT
this is my code so far, but it doesn't work.
import java.util.*;
import java.io.*;
class Main {
public static String LetterChanges(String str) {
// code goes here
String alphabet = "abcdefghijklmnopqrstuvwxyz";
String newWord = "";
for (int i = 0; i < str.length(); i++){
for (int j = 0; j < alphabet.length(); i++){
if (str[i] == alphabet[i]){
if (alphabet[i+1].isVowel()){
newWord = newWord + toUpperCase(alphabet[i+1]);
}
else{
newWord = newWord + alphabet[i+1];
}
}
}
}
return str;
}
public static void main (String[] args) {
// keep this function call here
Scanner s = new Scanner(System.in);
System.out.print(LetterChanges(s.nextLine()));
}
}
Can't I ask for the index position of a Char that is a part of a String? in C I could do that.
Other than that not sure why it doesn't work.
I would definitely go with method 1.
I believe what you're looking for is the indexOf method on a String.
First of, I would create a method that given a character finds the next letter in the alphabet and return that. This could be done by finding the letter in your alphabet string and then fetch the letter at index+1. As you also pointed out you would need to take care of the edge case to turn 'z' into 'a', could by done with an if-statement or by having an extra letter 'a' at the end of your alphabet string.
Now all that remains to do is create a loop that runs over all characters in the message and calls the previously made method on that character and constuct a new string with the output.
Hope this helps you figure out a solution.
Assuming that there would be only lower case English letters in the given String the most performant way would be to add +1 to every character, and use either if-statement checking whethe the initial character was z or use the modulo operator % as #sp00m has pointed out in the comment.
Performing a search in the alphabetic string (option 1 in your list) is redundant, as well extracting array char[] from the given string (option 3).
Checking the edge case:
public static String shiftLetters(String str) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char next = str.charAt(i);
if (next == 'z') result.append('a'); // checking the edge case
else result.append((char) (next + 1));
}
return result.toString();
}
Applying modulo operator:
public static String shiftLetters(String str) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char next = (char) ((str.charAt(i) - 'a' + 1) % 26 + 'a');
result.append(next);
}
return result.toString();
}
main()
public static void main(String[] args) {
System.out.println(shiftLetters("abc"));
System.out.println(shiftLetters("wxyz"));
}
Output:
bcd // "abc"
xyza // "wxyz"
Currently trying to program a poem Palindrome checker. This is not for palindromes specifically, but that the array has words in the same order both ways. For example the following is a poem palindrome
Life-
imitates nature,
always moving, traveling continuously.
Continuously traveling, moving always,
nature imitates
life
My issue is iterating through the array to match the first and last elements, as currently it compares things in the wrong order.
My code is as follows:
import java.util.Scanner;
import java.io.*;
public class WordPalindromeTest {
public static void main(String[] args) {
System.out.println("This program determines if an entered sentence/word poem is a palindrome.");
Scanner input = new Scanner(System.in);
System.out.println("Please enter a string to determine if it is a palindrome: ");
while(input.hasNextLine()) {
String palin = input.nextLine();
if(palin.equals("quit")) {
break;
}
else {
boolean isPalin = isWordPalindrome(palin);
if(isPalin == true) {
System.out.println(palin + " is a palindrome!");
}
else
System.out.println(palin + " is NOT a palindrome!");
}
}
System.out.println("Goodbye!");
input.close();
}
public static boolean isWordPalindrome(String s) {
boolean isWordPal = false;
String lowerCase = s.toLowerCase();
String replaced = lowerCase.replaceAll("[^a-zA-Z0-9\\s]", "");
String words[] = replaced.split(" ");
for(int i = 0; i < words.length; i++) {
for(int j = 0; j < words.length; j++) {
if (words[i].equals(words[j]) && i != j) {
isWordPal = true;
}
else
isWordPal = false;
}
}
return isWordPal;
}
}
With the specific point in question being
public static boolean isWordPalindrome(String s) {
boolean isWordPal = false;
String lowerCase = s.toLowerCase();
String replaced = lowerCase.replaceAll("[^a-zA-Z0-9\\s]", "");
String words[] = replaced.split(" ");
for(int i = 0; i < words.length; i++) {
for(int j = 0; j < words.length; j++) {
if (words[i].equals(words[j]) && i != j) {
isWordPal = true;
}
else
isWordPal = false;
}
}
return isWordPal;
}
I am confused on how to properly set up the loop to compare the right elements. It should compare the first element to the last, the second to the second to last, etc. until the loop is finished. I realize I have it compare the first to the entire array before moving on.
This seems like a homework assignment so I won't give you a working solution. But this of it like this:
-You don't need two loops. You only need to compare the first to the last, the second to the second to last, etc. (Hint: if you subtract i-1 from the length of the Array you'll get the corresponding element to i that you need to compare to). Also you only need to iterate over half of the length of the Array
-If ever isWordPal becomes false, you need to return false. Otherwise it might get overwritten and at the end it will return true.
I'm having trouble printing off all vowel combinations of a given input. My input is "SOMETHING" and I would like to print off all vowel combinations such as sxmxthxng where x is aeiou vowels. I believe my problem is that I find a vowel, change it with all the others vowels and move on. I need to continue down the rest of the word and find additional vowels and change those before proceeding.
Other refs
vowelList is an ArrayList containing all lower case vowels.
Code
private static void createVowelCombos(String word) {
Set<String> rmRepeats = new HashSet<>();
StringBuilder sbAddWord = new StringBuilder(word);
String[] splitWord = word.split("");
for (int i = 0; i < word.length(); i++) {
// System.out.println("real word: " + splitWord[i]);
if (splitWord[i].matches(".*[aeiou]")) {
// System.out.println("Split: " + splitWord[i]);
for (int j = 0; j < 5; j++) {
sbAddWord.setCharAt(i, vowelList.get(j).charAt(0));
System.out.println(sbAddWord.toString());
}
}
}
}
Sample Output with input "SOMETHING"
samething
semething
simething
something
sumething
sumathing
sumething
sumithing
sumothing
sumuthing
sumuthang
sumutheng
sumuthing
sumuthong
sumuthung
For some reason it is giving me all the combinations with 'u' but not the other vowels. I would like to get all the results for the other vowels as well.
as already suggested your problem can be best solved by using recursion (with backtracking). I've modified your code so as to print the required output. Have a look !!
private static void createVowelCombos(String word, int start) {
StringBuilder sbAddWord = new StringBuilder(word);
String[] splitWord = word.split("");
if(start==splitWord.length)
{
System.out.println(word);
return;
}
if (splitWord[start].matches(".*[aeiou]")) {
// System.out.println("Split: " + splitWord[i]);
for (int j = 0; j < 5; j++) {
sbAddWord.setCharAt(start, vowelList.get(j).charAt(0));
createVowelCombos(sbAddWord.toString(),start+1);
//System.out.println(sbAddWord.toString());
}
}
else
createVowelCombos(sbAddWord.toString(),start+1);
}
Call createVowelCombos("something",0) from the calling method.
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 wrote this program for school and it almost works, but there is one problem. The goal of the program is to take an inputted string and create a new string out of each word in the input beginning with a vowel.
Example:
input: It is a hot and humid day.
output: Itisaand.
Here is the driver:
public class Driver {
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
System.out.print("Input: ");
String input = console.nextLine();
Class strings = new Class(input);
int beg=0;
for(int j=0;j<input.length();j++)
{
if(strings.isVowel(j)&&(j==0||input.charAt(j-1)==' '))
beg=j;
else if(strings.endWord(j)&&(beg==0||input.charAt(beg-1)==' '))
{
strings.findWord(beg, j);
}
}
System.out.print("Output: ");
strings.printAnswer();
}
}
And here is the class:
public class Class {
String input="",answer="";
public Class(String input1)
{
input = input1;
}
public boolean isVowel(int loc)
{
return (input.charAt(loc)=='U'||input.charAt(loc)=='O'||input.charAt(loc)=='I'||input.charAt(loc)=='E'||input.charAt(loc)=='A'||input.charAt(loc)=='a'||input.charAt(loc)=='e'||input.charAt(loc)=='i'||input.charAt(loc)=='o'||input.charAt(loc)=='u');
}
public boolean endWord(int loc)
{
return (input.charAt(loc)==' '||input.charAt(loc)=='.'||input.charAt(loc)=='?'||input.charAt(loc)=='!');
}
public void findWord(int beg,int end)
{
answer = answer+(input.substring(beg,end));
}
public void printAnswer()
{
System.out.println(answer+".");
}
}
With this code, i get the output:
Itisaa hotandand humidand humid summerand humid summer day.
By removing this piece of code:
&& (j == 0 || input.charAt(j-1) == ' ')
I get the proper output, but it doesn't work if an inputted word has more than one vowel in it.
For example:
input: Apples and bananas.
output: and.
Can someone please explain:
a) why the code is printing out words beginning with consonants as it is and
b) how I could fix it.
Also, the methods in the class I've written can't be changed.
Here's a better algorithm:
split the input into an array of words
iterate over each word
if the word begins with a vowel, append it to the output
The easiest way to split the input would be to use String.split().
Here's a simple implementation:
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
String input = console.nextLine();
String[] words = input.split(" ");
StringBuilder output = new StringBuilder();
for (String s : words) {
if (startsWithVowel(s)) {
output.append(s);
}
else {
output.append(getPunc(s));
}
}
System.out.println(output.toString());
}
public static boolean startsWithVowel(String s) {
char[] vowels = { 'a', 'e', 'i', 'o', 'u' };
char firstChar = s.toLowerCase().charAt(0);
for (char v : vowels) {
if (v == firstChar) {
return true;
}
}
return false;
}
public static String getPunc(String s) {
if (s.matches(".*[.,:;!?]$")) {
int len = s.length();
return s.substring(len - 1, len);
}
return "";
}
The problem with your code was:
It was counting the same word multiple times, due to it finding vowels and starting the word search process over again.
Heres how I went about solving the problem, while still keeping your code looking relatively the same: All I changed was your loop
for(int i=0;i<input.length();i++)
{
if(strings.isVowel(i) &&(i==0 || strings.endWord(i-1))){
beg = i;
for(int j = i; j < input.length();j++) //look for end of word
{
if(strings.endWord(j)) //word has ended
{
i = j; //start from end of last word
strings.findWord(beg, j);
break; //word done, end word search
}
}
}
}
As mentioned above, there are better ways to go about this, and there are some pretty glaring flaws in the setup, but you wanted an answer, so here you go
Normally i would suggest you where to fix your code, but it's seems there is a lot of bad code practice in here.
Mass Concatenation should be apply be StringBuilder.
Never call a class Class
Conditions are too long and can be shorten by a static string of Vowels and apply .contains(Your-Char)
Spaces, Indentations required for readability purposes.
A different way of attacking this problem, may probably accelerate your efficiency.
Another approch will be Split the code by spaces and loop through the resulted array for starting vowels letters and then Append them to the result string.
A better readable and more maintainable version doing what you want:
public static String buildWeirdSentence(String input) {
Pattern vowels = Pattern.compile("A|E|I|O|U|a|e|i|o|u");
Pattern signs = Pattern.compile("!|\\.|,|:|;|\\?");
StringBuilder builder = new StringBuilder();
for (String word : input.split(" ")) {
String firstCharacter = word.substring(0, 1);
Matcher vowelMatcher = vowels.matcher(firstCharacter);
if (vowelMatcher.matches()) {
builder.append(word);
} else {
// we still might want the last character because it might be a sign
int wordLength = word.length();
String lastCharacter = word.substring(wordLength - 1, wordLength);
Matcher signMatcher = signs.matcher(lastCharacter);
if (signMatcher.matches()) {
builder.append(lastCharacter);
}
}
}
return builder.toString();
}
In use:
public static void main(String[] args) {
System.out.println(buildWeirdSentence("It is a hot and humid day.")); // Itisaand.
}
I think best approach is to split input and then check each word if it starts with vowel.
public static void main(String[] args)
{
Scanner console = new Scanner(System.in);
System.out.print("Input: ");
String str = console.next();
String[] input = str.split(" ");
StringBuilder s = new StringBuilder();
String test;
for (int i = 0; i < input.length; i++)
{
test = input[i];
if (test.charAt(0) == 'U' || test.charAt(0) == 'O'
|| test.charAt(0) == 'I' || test.charAt(0) == 'E'
|| test.charAt(0) == 'A' || test.charAt(0) == 'a'
|| test.charAt(0) == 'e' || test.charAt(0) == 'i'
|| test.charAt(0) == 'o' || test.charAt(0) == 'u')
{
s.append(input[i]);
}
}
System.out.println(s);
}
The problem with your code is that you override the first beg when a word has more that vowel. for example with Apples beg goes to 0 and before you could call findWord to catch it, it gets overridden with 4 which is the index of e. And this is what screws up your algorithm.
You need to note that you have already found a vowel until you have called finWord, for that you can add a boolean variable haveFirstVowel and set it the first time you have found one to true and only enter the branch for setting that variable to true if you haven't already set it. After you have called findWord set it back to false.
Next you need to detect the start of a word, otherwise for example the o of hot could wrongly signal a first vowel.
Class strings = new Class(input);
int beg = 0;
boolean haveFirstVowel = false;
for (int j = 0; j < input.length(); j++) {
boolean startOfWord = (beg == 0 || input.charAt(j - 1) == ' ');
if (startOfWord && ! haveFirstVowel && strings.isVowel(j)) {
beg = j;
haveFirstVowel = true;
}
else if (strings.endWord(j) && haveFirstVowel) {
strings.findWord(beg, j);
haveFirstVowel = false;
}
}
System.out.print("Output: ");
strings.printAnswer();
I think overall the algorithm is not bad. It's just that the implementation can definitely be better.
Regarding to the problem, you only need to call findWord() when:
You have found a vowel, and
You have reached the end of a word.
Your code forgot the rule (1), therefore the main() can be modified as followed:
Scanner console = new Scanner(System.in);
System.out.print("Input: ");
String input = console.nextLine();
Class strings = new Class(input);
int beg = 0;
boolean foundVowel = false; // added a flag indicating whether a vowel has been found or not
for (int j = 0; j < input.length(); j++) {
if (strings.isVowel(j) && (j == 0 || input.charAt(j - 1) == ' ')) {
beg = j;
foundVowel = true;
} else if (strings.endWord(j) && (beg == 0 || input.charAt(beg - 1) == ' ')) {
if (foundVowel) { // only call findWord() when you have found a vowel and reached the end of a word
strings.findWord(beg, j);
foundVowel = false; // remember to reset the flag
}
}
}
System.out.print("Output: ");
strings.printAnswer();