Print vowels from a word in Java - java

I am a beginner at java and I am doing this course an needed some help with this. Basically, a user will input a string and then the program will print out only the vowels on one line.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
System.out.print("In:");
String word = inp.nextLine();
//write your code below
for(int whatsat = 0; whatsat < word.length(); whatsat++){
if (word.charAt(whatsat).equals("a")){ //how to declare mutiple letters?
System.out.print(word.charAt(whatsat));
}
}
}
}

I agree with #Logan. You don't use equals() to compare primitive type values (int, char, boolean, etc.), just use simple == expression.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
System.out.print("In:");
String word = inp.nextLine();
//write your code below
for(int whatsat = 0; whatsat < word.length(); whatsat++){
char c = Character.toLowerCase(word.charAt(whatsat));
if (c == 'a' || c == 'e'|| c == 'i' || c == 'o' || c == 'u'){
System.out.print(word.charAt(whatsat));
}
}
}
}

A simple way to do this (intentionally avoiding complex regex options) would be to use the String.indexOf() method within your loop.
In the example below, we basically check if "AEIOUaeiou" contains the char that we're pulling from the user's input. If so, we extract it:
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
System.out.print("In:");
String word = inp.nextLine();
//write your code below
// This will hold any matching vowels we find
StringBuilder sb = new StringBuilder();
for (int i = 0; i < word.length(); i++) {
// Check if our list of vowels contains the current char. If the current char exists in the String of vowels, it will have an index of 0 or greater.
if ("AEIOUaeiou".indexOf(word.charAt(i)) > -1) {
// If so, add it to our StringBuilder
sb.append(word.charAt(i));
}
}
// Finally, print the result
System.out.println(sb.toString());
}
The Result:
With test input of "This is my test input. Did it work?" the output is: iieiuiio

So there's two issues here:
Characters are compared differently from Strings.
Checking for multiple characters.
To compare characters, do something like:
if (word.charAt(whatsat) == 'a') {
...
}
Note the single quotes! 'a' not "a"!
If you're asking "why are comparisons for strings and characters different?", that's a good question. I actually don't know the reason, so we should both research it. Moving on.
To check for multiple characters:
for(int whatsat = 0; whatsat < word.length(); whatsat++){
if (word.charAt(whatsat) == 'a' || word.charAt(whatsat) == 'e' || word.charAt(whatsat) == 'i'){
System.out.print(word.charAt(whatsat));
}
}
Note that if you're input has capital letters, you'll need to either:
Convert your input to lowercase so you can just check for lowercase letters, or
Explicitly check for capital letters in your if statement, e.g
if (...word.charAt(whatsat) == 'A' ...)
Longterm, you'll want to research regular expressions like a Adrian suggested in the comments. It may be complicated for a beginning student, but if you're interested you should look into it.
Hope this helps.

I am really surprised nobody has suggested using Enums... Cleanest way and simplest way, in my opinion.
Simply define an Enum with all the vowels, go through the String and compare each character to the values inside of Enum, ignoring the case - note the cast of char into String. If it is present in the Enum, print it out.
public class VowelFind {
enum Vowels {
A, E, I, O, U
}
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
System.out.print("In:");
String word = inp.nextLine();
for (int i = 0; i < word.length(); i++) { //loop through word
for (Vowels v : Vowels.values()) { //loop through Enum values
if((word.charAt(i)+"").equalsIgnoreCase(v.name())) { //compare character to Enum value, ignoring case
System.out.print(word.charAt(i));
}
}
}
}
}
Input: Hello World
Output: eoo

I prefer to use Hashmap as lookup is O(1)
public class PrintVowelsInWord {
public static Map<Character, Character> vowels;
public static void main(String[] args) {
loadMap();
// for simplicity sake I am not using Scanner code here
getVowels("wewillrockyou");
}
public static void loadMap() {
if (vowels == null) {
vowels = new HashMap<>();
vowels.put('a', 'a');
vowels.put('e', 'e');
vowels.put('i', 'i');
vowels.put('o', 'o');
vowels.put('u', 'u');
}
}
public static void getVowels(String input) {
for (Character letter : input.toCharArray()) {
if (vowels.containsKey(letter)) {
System.out.print(letter);
}
}
}
}

Related

What is the best way to replace a letter with the letter following it in the alphabet in Java?

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"

How to get each letter and add them as points with a substring method

I've been trying to create an algorithm where each letter adds points. I don't want to use charAt, I'd like to use the substring method.
My problem is that String letter does not seem to get each letter and the result is always 0.
Is there a way to get each letter and convert it to points?
public class WDLPoints{
public static void main(String[] args){
String word = "LDWWL";
System.out.println(getMatchPoints(word));
}
public static int getMatchPoints(String word) {
int points = 0;
String letter = word.substring(5);
for (int i = 0; i < word.length(); i++) {
if (letter.equals("W")) {
points+=3;
}
else if (letter.equals("D")) {
points+=1;
}
else {
points = 0;
}
}
return points;
}
}
You may try the following changes in your public static int getMatchPoints(String word) method:
for (int i = 0; i < word.length(); i++) {
String letter = word.substring(i, i + 1);
if (letter.equals("W")) {
points+=3;
}
else if (letter.equals("D")) {
points+=1;
}
}
word.substring(i, i + 1) will get a single letter word and will help you compute your score the way you want.
If you want to make it really simple you can just use String.toCharArray() and then iterate over the array of char and check its value:
public static int getMatchPoints(String word) {
int points = 0;
char[] arr = word.toCharArray();
for (char letter : arr) {
if (letter == 'W') {
points += 3;
}
else if (letter == 'D') {
points += 1;
}
}
return points;
}
I also removed your else statement because that was just setting the value to 0 if there is any other letter in the loop. I think you intended it to be points += 0 which does nothing, so it can just be removed.
Example Run:
Input:
String word = "LDWWL";
Output:
7
Note: I am aware you might not be allowed to use this solution, but I thought it would be good info on the possibilities since it does not technically use charAt()
Also I'd like to point out you misunderstand what substring(5) does. This will return all characters after the position of 5 as a single String, it does not separate the String into different characters or anything.
You will find that your variable letter is always the empty String. Here's a better way of doing things:
class WDLPoints
{
public static void main(String[] args)
{
String word = "LDWWL";
System.out.println(getMatchPoints(word));
}
// We have only one method to encode character values, all in one place
public static int getValueForChar(int c)
{
switch((char)c)
{
case 'W': return 3;
case 'D': return 1;
default: return 0; //all non-'W's and non-'D's are worth nothing
}
}
public static int getMatchPoints(String word)
{
// for all the characters in the word
return word.chars()
// get their integer values
.map(WDLPoints::getValueForChar)
// and sum all the values
.sum();
}
}
Assuming your string represents a football teams performance of the last 5 games, you could keep it simple and readable with something like:
public static int getMatchPoints(String word) {
String converted = word.replace('W', '3').replace('D', '1').replace('L', '0');
return converted.chars().map(Character::getNumericValue).sum();
}
This converts your example input "LDWWL" to "01330" and sums each char by getting its numeric value.

Reduction of duplicate words prior to uppercase or lowercase

Main
public class Main
{
public static void main(String[] args)
{
System.out.println(Dupe.Eliminate("Testing UppeR and loweR"));
System.out.println(Dupe.Eliminate("UppeR is BetteR"));
}
}
Class
public class Dupe
{
public static String Eliminate(String input)
{
char[] chrArray = input.toCharArray();
String letter ="";
for (char value:chrArray){
if (letter.indexOf(value) == -1){
letter += value;
}
}
return letter;
}
}
I am trying to eliminate duplicate letters e.g. Hello would be Helo. Which I have achieved, however, what I want to implement is that it won't matter if it's uppercase or lowercase, it will still be classed as a duplicate so Hehe would be He, not Heh. Should I .equals... each individual letter or is there an efficient way? sorry for asking if it's simple question for you guys.
This is how I would approach this. This might not be the most efficient way to do it, but you can try this.
public class Main
{
public static void main(String[] args)
{
System.out.println(Dupe.Eliminate("Testing UppeR and loweR"));
}
}
class Dupe
{
public static String Eliminate(String input)
{
char[] chrArray = input.toCharArray();
String letter ="";
for(int index = 0; index < chrArray.length; index++)
{
int j = 0;
boolean flag = true;
//this while loop is used to check if the next character is already existed in the string (ignoring the uppercase or lowercase)
while(j < letter.length())
{
if((int)chrArray[index] == letter.charAt(j) || (int)chrArray[index] == ((int)letter.charAt(j)+32) ) //32 is because the difference between the ascii value of the uppercase and lowercase letter is 32
{
flag = false;
break;
}
else
j++;
}
if(flag == true)
{
letter += chrArray[index];
}
}
return letter;
}
}
you can have 2 checks in place with upper case and lower case characters:
public static String Eliminate(String input)
{
char[] chrArray = input.toCharArray();
String letter ="";
for (char value:chrArray){
if (letter.indexOf(value.toLowerCase()) == -1 && letter.indexOf(value.toUpperCase()) == -1){
letter += value;
}
}
return letter;
}
Here you go, this will replace all duplicate characters no matter how many in the sequence.
public static void main(String[] args)
{
String duped = "aaabbccddeeffgg";
final Pattern p = Pattern.compile("(\\w)\\1+");
final Matcher m = p.matcher(duped);
while (m.find())
System.out.println("Duplicate character " + (duped = duped.replaceAll(m.group(), m.group(1))));
}
If you are looking for duplicates like: abacd to replace both a's, try this as the regex given in Pattern.compile(".*([0-9A-Za-z])\\1+.*")
Here's another (stateful) way to do it:-
String s = "Hehe";
Set<String> found = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
String result = s.chars()
.mapToObj(c -> "" + (char) c)
.filter(found::add)
.collect(Collectors.joining());
System.out.println(result);
Output: He

How to count number of letters in sentence

I'm looking for simple way to find the amount of letters in a sentence.
All I was finding during research were ways to find a specific letter, but not from all kinds.
How I do that?
What I currently have is:
sentence = the sentence I get from the main method
count = the number of letters I want give back to the main method
public static int countletters(String sentence) {
// ....
return(count);
}
You could manually parse the string and count number of characters like:
for (index = 1 to string.length()) {
if ((value.charAt(i) >= 'A' && value.charAt(i) <= 'Z') || (value.charAt(i) >= 'a' && value.charAt(i) <= 'z')) {
count++;
}
}
//return count
A way to do this could stripping every unwanted character from the String and then check it's length. This could look like this:
public static void main(String[] args) throws Exception {
final String sentence = " Hello, this is the 1st example sentence!";
System.out.println(countletters(sentence));
}
public static int countletters(String sentence) {
final String onlyLetters = sentence.replaceAll("[^\\p{L}]", "");
return onlyLetters.length();
}
The stripped String looks like:
Hellothisisthestexamplesentence
And the length of it is 31.
This code uses String#replaceAll which accepts a Regular Expression and it uses the category \p{L} which matches every letter in a String. The construct [^...] inverts that, so it replaces every character which is not a letter with an empty String.
Regular Expressions can be expensive (for the performance) and if you are bound to have the best performance, you can try to use other methods, like iterating the String, but this solution has the much cleaner code. So if clean code counts more for you here, then feel free to use this.
Also mind that \\p{L} detects unicode letters, so this will also correctly treat letters from different alphabets, like cyrillic. Other solutions currently only support latin letters.
SMA's answer does the job, but it can be slightly improved:
public static int countLetters(String sentence) {
int count = 0;
for (int i = 0; i < sentence.length; i ++)
{
char c = Character.toUpperCase(value.charAt(i));
if (c >= 'A' && c <= 'Z')
count ++;
}
return count;
}
This is so much easy if you use lambda expression:
long count = sentence.chars().count();
working example here: ideone
use the .length() method to get the length of the string, the length is the amount of characters it contains without the nullterm
if you wish to avoid spaces do something like
String input = "The quick brown fox";
int count = 0;
for (int i=0; i<input.length(); i++) {
if (input.charAt(i) != ' ') {
++count;
}
}
System.out.println(count);
if you wish to avoid other white spaces use a regex, you can refer to this question for more details
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
String str = sc.nextLine();
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (Character.isLetter(str.charAt(i)))
count++;
}
System.out.println(count);
}
}

Java program that does simple string manipulation is not working correctly

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();

Categories

Resources