I have to write a program that takes a String as user input and then prints a substring that starts with the first vowel of the String and ends with the last. So for instance if my String is : "Hi I have a dog named Patch", the printed substring would be : "i I have a dog named Pa"
This is the code I have now:
import java.util.Scanner;
import java.util.*;
public class SousChaineVoyelle {
private static Scanner sc;
public static void main (String[] args) {
sc = new Scanner(System.in);
System.out.print("Enter a String: ");
String str = sc.nextLine();
int pos1 = 0;
int pos2 = 0;
int i;
int j;
boolean isVowel1 = false;
boolean isVowel2 = false;
for (i = 0; i < str.length(); i++){
if (str.charAt(i) == 'A' || str.charAt(i) == 'a' ||
chaine.charAt(i) == 'E' || str.charAt(i) == 'e' ||
str.charAt(i) == 'I' || str.charAt(i) == 'i' ||
str.charAt(i) == 'O' || str.charAt(i) == 'o' ||
str.charAt(i) == 'U' || str.charAt(i) == 'u' ||
str.charAt(i) == 'Y' || str.charAt(i) == 'y'){
isVowel1 = true;
break;
}
}
if (isVowel1){
pos1 = str.charAt(i);
}
for (j = str.length() - 1; j > i; j--){
if (str.charAt(j) == 'A' || str.charAt(j) == 'a' ||
str.charAt(j) == 'E' || str.charAt(j) == 'e' ||
str.charAt(j) == 'I' || str.charAt(j) == 'i' ||
str.charAt(j) == 'O' || str.charAt(j) == 'o' ||
str.charAt(j) == 'U' || str.charAt(j) == 'u' ||
str.charAt(j) == 'Y' || str.charAt(j) == 'y'){
isVowel2 = true;
break;
}
}
if (isVowel2){
pos2 = str.charAt(j);
}
String sub = chaine.substring(pos1, pos2);
System.out.print(The substring from the first vowel to the last is "\"" + sub +"\"");
}
}
this got me this:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
at java.base/jdk.internal.util.Preconditions$1.apply(Preconditions.java:55)
at java.base/jdk.internal.util.Preconditions$1.apply(Preconditions.java:52)
at java.base/jdk.internal.util.Preconditions$4.apply(Preconditions.java:213)
at java.base/jdk.internal.util.Preconditions$4.apply(Preconditions.java:210)
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:98)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302)
at java.base/java.lang.String.checkIndex(String.java:4557)
at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:46)
at java.base/java.lang.String.charAt(String.java:1515)
at SousChaineVoyelle.main(SousChaineVoyelle.java:33)
One way of looking at it is you have a lot of code to do a simple thing, which means more chances for bugs and errors.
Here's a "less code" solution:
str = str.replaceAll("(?i)^[^aeiou]*|[^aeiou]*$", "");
See live demo.
This works by matching all leading and trailing non-vowels (if any) and replacing them with nothing, effectively deleting them.
(?i) makes the match case insensitive.
After the first for loop, i will be str.length() no matter what. You may want to create another variable to hold I when it's found to remedy this.
Related
I can't seem to find the problem with this code. I am trying to convert a phone number which is comprised of numbers and letters to numbers only. For example, 1800SMILEING should translate to 1800-764-5464. But my code repeats the last digit in each group. 180048-766-5466 instead of the correct format. It also generates the additional 48 after 800.
Please help, I've been working on this for many hours for my Java course homework but I can't figure out the problem.
import java.util.Scanner;
public class PhoneNumberConverter {
public static void main(String[] args) {
System.out.println("Enter a phone number to convert:");
Scanner input = new Scanner(System.in);
String phoneNumber = input.next();
input.close();
int firstGroup = translatePhoneNumber (phoneNumber, 0, 4);
System.out.print(firstGroup);
System.out.print("-");
int secondGroup = translatePhoneNumber (phoneNumber, 4, 6);
System.out.print(secondGroup);
System.out.print("-");
int thirdGroup = translatePhoneNumber (phoneNumber, 7, 10);
System.out.print(thirdGroup);
}
public static int translatePhoneNumber (String phoneNumber, int firstIndex, int lastIndex) {
int chartoNumber = 'A';
int currentIndex;
if (firstIndex != 0) {
for (currentIndex = firstIndex; currentIndex < lastIndex; currentIndex++) {
if (phoneNumber.charAt(currentIndex) == 'A' || phoneNumber.charAt(currentIndex) == 'B' || phoneNumber.charAt(currentIndex) == 'C' )
chartoNumber = 2;
else if (phoneNumber.charAt(currentIndex) == 'D' || phoneNumber.charAt(currentIndex) == 'E' || phoneNumber.charAt(currentIndex) == 'F' )
chartoNumber = 3;
else if (phoneNumber.charAt(currentIndex) == 'G' || phoneNumber.charAt(currentIndex) == 'H' || phoneNumber.charAt(currentIndex) == 'I' )
chartoNumber = 4;
else if (phoneNumber.charAt(currentIndex) == 'J' || phoneNumber.charAt(currentIndex) == 'K' || phoneNumber.charAt(currentIndex) == 'L' )
chartoNumber = 5;
else if (phoneNumber.charAt(currentIndex) == 'M' || phoneNumber.charAt(currentIndex) == 'N' || phoneNumber.charAt(currentIndex) == 'O' )
chartoNumber = 6;
else if (phoneNumber.charAt(currentIndex) == 'P' || phoneNumber.charAt(currentIndex) == 'Q' || phoneNumber.charAt(currentIndex) == 'R' || phoneNumber.charAt(currentIndex) == 'S' )
chartoNumber = 7;
else if (phoneNumber.charAt(currentIndex) == 'T' || phoneNumber.charAt(currentIndex) == 'U' || phoneNumber.charAt(currentIndex) == 'V' )
chartoNumber = 8;
else if (phoneNumber.charAt(currentIndex) == 'W' || phoneNumber.charAt(currentIndex) == 'X' || phoneNumber.charAt(currentIndex) == 'Y' || phoneNumber.charAt(currentIndex) == 'Z' )
chartoNumber = 9;
else
chartoNumber = phoneNumber.charAt(currentIndex);
System.out.print(chartoNumber);
}
} else {
for (currentIndex = firstIndex; currentIndex < lastIndex; currentIndex++) {
chartoNumber = phoneNumber.charAt(currentIndex);
char numbeeer = (char) chartoNumber;
System.out.print(numbeeer);
}
}
return chartoNumber;
}
}
Firstly note that you are printing out your result in the translatePhoneNumber method itself, you there is not need to print out the result again.
Get rid of System.out.print(firstGroup); etc.
Second, if (firstIndex != 0) { - why? Note that you are doing translatePhoneNumber (phoneNumber, 0, 4); so firstIndex will be 0
Personally I would just pass the substring to the method and loop for each char.
translatePhoneNumber (phoneNumber.substring (0, 4));
....
for (char c : localPhoneNumber) {
// your mapping
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm trying to count words by using whitespace as my indicator for when there is a new word.
My current code is returning crazy results for wordCounter, but my vowelCounter is working perfectly.
I apologize if this is a basic or simple question...I'm just starting out with Java and I would really appreciate any assistance!
System.out.println("Please enter some text: ");
String fileContent = input.nextLine().toLowerCase();
int vowelCounter = 0;
int wordCounter = 0;
for (int i = 0; i < fileContent.length(); i++) {
if(fileContent.charAt(i) == 'a' || fileContent.charAt(i) == 'e' || fileContent.charAt(i) == 'i'|| fileContent.charAt(i) == 'o' || fileContent.charAt(i) == 'u')
vowelCounter++;
for (int j = 0; j < fileContent.length(); j++) {
if (Character.isWhitespace(fileContent.charAt(j))) {
wordCounter++;
}
}
}
System.out.println("\nVowel Counter: " + vowelCounter);
System.out.println("Word Counter: " + wordCounter);
That is what happens when you have bad indentation. You are having nested for-loops instead of 2 separate for-loops.
Separate your loops like:
for (int i = 0; i < fileContent.length(); i++) {
if(fileContent.charAt(i) == 'a' || fileContent.charAt(i) == 'e' || fileContent.charAt(i) == 'i'|| fileContent.charAt(i) == 'o' || fileContent.charAt(i) == 'u')
vowelCounter++;
}
for (int j = 0; j < fileContent.length(); j++) {
if (Character.isWhitespace(fileContent.charAt(j)))
wordCounter++;
}
Or have them in 1 single for-loop:
for (int i = 0; i < fileContent.length(); i++) {
if(fileContent.charAt(i) == 'a' || fileContent.charAt(i) == 'e' || fileContent.charAt(i) == 'i'|| fileContent.charAt(i) == 'o' || fileContent.charAt(i) == 'u')
vowelCounter++;
else if (Character.isWhitespace(fileContent.charAt(i))) {
wordCounter++;
}
}
Above all, to check that specific characters (such as vowels) exist in your string, you can do it as:
char ch = fileContent.charAt(i);
if("aeiou".contains("" + ch))
You have a redundant loop inside your loop. Just add the second if to the same loop:
for (int i = 0; i < fileContent.length(); i++) {
if(fileContent.charAt(i) == 'a' || fileContent.charAt(i) == 'e' || fileContent.charAt(i) == 'i'|| fileContent.charAt(i) == 'o' || fileContent.charAt(i) == 'u')
vowelCounter++;
else if (Character.isWhitespace(fileContent.charAt(i)))
wordCounter++;
}
You might wanna add 1 to the wordcount because it ia counting the number of whitespaces. For eg: in "apple banana", there is 1 whitespace but 2 words. Besides that, counting whitespaces has shortcomings, for instance, when there are two or more consecutive whitespaces between the words.
I have been stuck for quite some time. I would need to ignore digits entered, blank spaces and special characters like $^%##&! and just read the other letters a-z, using Character.isDigit & Character.isLetter.. I have tried using the both methods, it didn't work out for me.. Please advice..
The error:
The normal output (without spaces and digits) :
The expected output should be 438-5626 even when I entered 123$#GetLoan.. They should ignore the first few characters '123$#' and read only GetLoan..
Full Question: Write a program that prompts the user to enter a telephone number expressed in letters and outputs the corresponding telephone number in digits. If the user enters more than seven letters, then process only the first seven letters. Also output the – (hyphen) after the third digit. Allow the user to use both uppercase and lowercase letters as well as spaces between words.
public class Question3 {
public static void main(String[] args) {
String letters;
char phoneDigit;
Scanner kb = new Scanner(System.in);
System.out.println("Enter letters : ");
letters = kb.next();
for (int i = 0; i < 7; i++) {
phoneDigit = letters.charAt(i);
if (Character.isLetter(phoneDigit) == true) {
if (i == 3) {
System.out.println("-");
} //If
if (phoneDigit >= 'A' && phoneDigit <= 'C'
|| phoneDigit >= 'a' && phoneDigit <= 'c') {
System.out.println("2");
} else if (phoneDigit >= 'D' && phoneDigit <= 'F'
|| phoneDigit >= 'd' && phoneDigit <= 'f') {
System.out.println("3");
} else if (phoneDigit >= 'G' && phoneDigit <= 'I'
|| phoneDigit >= 'g' && phoneDigit <= 'i') {
System.out.println("4");
} else if (phoneDigit >= 'J' && phoneDigit <= 'L'
|| phoneDigit >= 'j' && phoneDigit <= 'l') {
System.out.println("5");
} else if (phoneDigit >= 'M' && phoneDigit <= 'O'
|| phoneDigit >= 'm' && phoneDigit <= 'o') {
System.out.println("6");
} else if (phoneDigit >= 'P' && phoneDigit <= 'S'
|| phoneDigit >= 'p' && phoneDigit <= 's') {
System.out.println("7");
} else if (phoneDigit >= 'T' && phoneDigit <= 'V'
|| phoneDigit >= 't' && phoneDigit <= 'v') {
System.out.println("8");
} else if (phoneDigit >= 'W' && phoneDigit <= 'Z'
|| phoneDigit >= 'W' && phoneDigit <= 'z') {
System.out.println("9");
} // If
} // If
} // For loop
} //PSVM
Below fragment is probably the problem:
for (int i = 0; i < 7; i++) {
phoneDigit = letters.charAt(i);
if (Character.isLetter(phoneDigit) == true) {
You are taking first 7 characters, and printing only the ones that are letters. So for input string 123getloan you will iterate over 123getl, and then isLetter will reject 123, so your program later will deal only with getl.
To iterate over only 7 letters you would need to change it to increment i only if given character is a letter e.g. by doing the below:
int i = 0;
for (char phoneDigit : letters.toCharArray()) {
if (Character.isLetter(phoneDigit)) {
i++;
// other ifs here
if (i == 3) {
System.out.println("-");
}
}
if (i >= 7) {
break;
}
}
EDIT: Fixed problem mentioned by #Andreas
This lab for my intro class requires us to return any user input in pig latin.
The error I seem to keep getting when I run it and type any string into the console is this:
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
The error is found here:
thisWord = x.substring(indexOfCurrentNonLetter +1, indexOfNextNonLetter);
I understand from another post this is the problem:
IndexOutOfBoundsException -- if the beginIndex is negative, or endIndex is >larger than the length of this String object, or beginIndex is larger than >endIndex.
Actually, your right edge of your substring function may be lower than the left >one. For example, when i=(size-1) and j=size, you are going to compute >substring(size-1, 1). This is the cause of you error. (Answer By Bes0ul)
My question is, what is the solution to this problem?
Here are the methods I am using:
public String pigLatin(String x)
{
String thisWord = "";
x += " ";
int indexOfNextNonLetter = 0, indexOfCurrentNonLetter = 0;
for(int i = 0; i < x.length(); i++)
{
System.out.println("At least the loop works"); //Let's play a game called find the issue
if(x.charAt(i) < 65 || x.charAt(i) > 90 && x.charAt(i) < 97 || x.charAt(i) > 122) //if it isn't a letter
{
phrase += x.charAt(i); // add our non character to the new string
for(int j = 0; j < x.substring(i).length(); j++) // find the next character that isn't a letter
{
if(x.charAt(i) < 65 || x.charAt(i) > 90 && x.charAt(i) < 97 || x.charAt(i) > 122)
{
indexOfNextNonLetter = j + i;
if(j+i > x.length())
System.out.print("Problem Here");
indexOfCurrentNonLetter = i;
System.out.println("noncharacter detected"); //I hope you found the issue
j = x.length();
thisWord = x.substring(indexOfCurrentNonLetter +1, indexOfNextNonLetter);//between every pair of nonletters exists a word
}
}
phrase += latinWord(thisWord); // translate the word
i = indexOfNextNonLetter - 1;
}
}
return phrase;
}
/*
* This converts the passed word to pig latin
*/
public String latinWord(String word)
{
String lWord = "";
String beforeVowel = "";
String afterVowel = "";
boolean caps = false;
char first = word.charAt(0);
if(first > 'A' && first < 'Z')
{
first = Character.toLowerCase(first); //If the first char is capital, we need to account for this
caps = true;
}
if(containsNoVowels(word))
lWord = Character.toUpperCase(first) + word.substring(1) + "ay"; //If we have no vowels
if(word.charAt(0) == 'A' || word.charAt(0) == 'a' || word.charAt(0) == 'E' || word.charAt(0) == 'e' || word.charAt(0) == 'I' || word.charAt(0) == '0'
|| word.charAt(0) == 'O' || word.charAt(0) == 'O' || word.charAt(0) == 'o' || word.charAt(0) == 'U' || word.charAt(0) == 'u')
{
lWord = Character.toUpperCase(first) + word.substring(1) + "yay"; //If the first char is a vowel
}
if(word.charAt(0) != 'A' || word.charAt(0) != 'a' || word.charAt(0) != 'E' || word.charAt(0) != 'e' || word.charAt(0) != 'I' || word.charAt(0) != '0'
|| word.charAt(0) != 'O' || word.charAt(0) != 'O' || word.charAt(0) != 'o' || word.charAt(0) != 'U' || word.charAt(0) != 'u')
{ //If the first letter isnt a vowel but we do have a vowel in the word
for(int m = 0; m < word.length(); m++)//if we have a vowel in the word but it doesn't start with a vowel
{
if(word.charAt(m) == 'A' || word.charAt(m) == 'a' || word.charAt(m) == 'E' || word.charAt(m) == 'e' || word.charAt(m) == 'I' || word.charAt(m) == 'm'
|| word.charAt(m) == 'O' || word.charAt(m) == 'O' || word.charAt(m) == 'o' || word.charAt(m) == 'U' || word.charAt(m) == 'u')
{
for(int l = 0; l < word.substring(m).length(); l++)
{
afterVowel += word.substring(m).charAt(l); //Build the part after the first vowel
}
m += word.length();
}
else
beforeVowel += word.charAt(m);
}
if(caps == false)
lWord = afterVowel + beforeVowel + "ay";
else
{
first = Character.toUpperCase(afterVowel.charAt(0));
}
}
return lWord;
}
/*
* This function checks the string letter by letter to see if any of the letters are vowels.If there are none it returns true
*/
public boolean containsNoVowels(String wrd)
{
for(int h = 0; h < wrd.length(); h++)
{
if(wrd.charAt(h) == 'A' || wrd.charAt(h) == 'a' || wrd.charAt(h) == 'E' || wrd.charAt(h) == 'e' || wrd.charAt(h) == 'I' || wrd.charAt(h) == 'h'
|| wrd.charAt(h) == 'O' || wrd.charAt(h) == 'O' || wrd.charAt(h) == 'o' || wrd.charAt(h) == 'U' || wrd.charAt(h) == 'u')
return false;
else
return true;
}
return false;
}
I think the error lies inside your second for loop within pigLatin():
for (int j = 0; j < x.substring(i).length(); j++) // find the next character that isn't a letter
{
if(x.charAt(i) < 65 || x.charAt(i) > 90 && x.charAt(i) < 97 || x.charAt(i) > 122)
The last line shown above starts checking at char i. This is the same char you just checked in the outer loop. So the test will succeed. And I think the logic breaks down either in this iteration or a subsequent one.
I think what you want is:
for(int j = 1; j < x.substring(i).length(); j++)
{
if (x.charAt(j) < 65 || x.charAt(j) > 90 && x.charAt(j) < 97 || x.charAt(j) > 122)
Note, there are two changes:
Initialise j at 1 to test the next character in the for statement
Test the jth character, not the ith in the if statement
I'm trying to write a program which declares and initializes an array of characters (char[] word) and calls the method:
public static int countVowels(char[])
which returns the number of vowels in word.
Can anyone tell me where im going wrong? Getting this error
java:11: error: char cannot be dereferenced
for (int j=0; j < word[i].length(); j++) {
^
array.java:12: error: char cannot be dereferenced
char c = word[i].charAt(j);
^
2 errors
public class array {
public static void main(String[] args) {
char[] word = {'a','b','f','u','g','i','o','r'};
}
public static int countVowels(char[] word) {
int vowelCount = 0;
for (int i = 0; i < word.length; i++)
{
for (int j=0; j < word[i].length(); j++) {
char c = word[i].charAt(j);
if ( (c == 'a')
|| (c == 'e')
|| (c == 'i')
|| (c == 'o')
|| (c == 'u')
|| (c == 'A')
|| (c == 'E')
|| (c == 'I')
|| (c == 'O')
|| (c == 'U')
)
vowelCount++;
}
}
}
}
You don't really need the inner loop. Try this:
public class array {
public static void main(String[] args) {
char[] word = {'a','b','f','u','g','i','o','r'};
}
public static int countVowels(char[] word) {
int vowelCount = 0;
for (int i = 0; i < word.length; i++)
{
char c = word[i];
if ( (c == 'a')
|| (c == 'e')
|| (c == 'i')
|| (c == 'o')
|| (c == 'u')
|| (c == 'A')
|| (c == 'E')
|| (c == 'I')
|| (c == 'O')
|| (c == 'U')
)
vowelCount++;
}
return vowelCount;
}
}
When you call word[i], you're getting the value stored at the ith position in the array word. So, word[i].length returns the length of the value stored in the ith position. You're getting an error because the value stored is a char, which doesn't have a length attribute. Instead, try just word.length. This will give you the length of the array.
With this information, you should have enough to fix your for loop code. Remember, word[i] returns a char.
Try word.length. The code should not run in the browser, because it's not javascript. instead it is java.
You have more than one error;
Just use these;
for (int j=0; j < word.length; j++) {
char c = word[i];
instead of these down below (these are invalid);
for (int j=0; j < word[i].length(); j++) {
char c = word[i].charAt(j);
To get the length of the array, length is enough, you don't have to put the paranthesis. And also when you assign the ith char element of the word array, c = word[i]; is valid.
I've just corrected your method and just have written a test code for it. You also used unnecessary outer for-loop, which causes invalid result.
Additional to your corrected method, I've added my method for counting vowels, which uses a secondary array for storing the vowels. It's much more readable but the choice is yours ;)
public class TestCountVowels {
public static void main(String[] args) {
char[] word = {'a','b','f','u','g','i','o','r'};
//I advice calling geVowelCount(char[]) method
System.out.println("Vowel count: " + getVowelCount(word) );
//Calling your method with my corrections
System.out.println("Vowel count: " + yourCountMethod(word) );
}
//My method for comparing char arrays and counting
public static int getVowelCount(char[] inputWord) {
char[] vowels = {'a','A','e','E','i','I','o','O','u','U'};
int vowelCount = 0;
for( int i = 0; i < inputWord.length; i++ ) {
for( int j = 0; j < vowels.length; j++ )
if ( inputWord[i] == vowels[j] ) {
vowelCount++;
continue;
}
}
return vowelCount;
}
//Your method with corrections
public static int yourCountMethod(char[] word) {
int vowelCount = 0;
for (int i = 0; i < word.length; i++)
{
char c = word[i];
if (
(c == 'a') ||
(c == 'e') ||
(c == 'i') ||
(c == 'o') ||
(c == 'u') ||
(c == 'A') ||
(c == 'E') ||
(c == 'I') ||
(c == 'O') ||
(c == 'U')
)
vowelCount++;
}
return vowelCount;
}
}
Hope that it helps.