How to insert a syllable before a single vowel - java

I try to insert a syllable before each vowel with the following restrictions:
- Before each following vowel (a, e, i, o, u), insert the stray syllable "av".
- Unless the vowel is preceded by another vowel
Actually I've done this
public static String translate(String text) {
char [] charArray = text.toCharArray();
StringBuilder sb = new StringBuilder();
for(char c : charArray) {
if (charArray.length < 255){
if (isVowel(c)) {
sb.append(String.format("av%s" , c));
}
else {
sb.append(c);
}
}
}
return sb.toString();
}
static boolean isVowel(char c) {
return (c == 'a') || (c == 'e') ||
(c == 'i') || (c == 'o') ||
(c == 'u');
}
With words without double vowels it works perfectly:
Cat becomes
Cavat
But with double vowel it doesn't work
Meet becomes
Maveavet // Should return Meet
How to check if 2 successive letters are vowels in order not to add the syllable if it's the case ?
Thanks in advance

Here is a version that uses an ordinary for loop:
public static String translate(String text) {
char [] charArray = text.toCharArray();
StringBuilder sb = new StringBuilder();
Set<Character> vowels = new HashSet<>(Arrays.asList('a','e','i','o','u'));
char cFirst = charArray[0];
if (vowels.contains(cFirst) && !(vowels.contains(charArray[1]))) {
sb.append(String.format("av%s" , cFirst));
}
else sb.append(cFirst);
for (int i = 1; i < charArray.length-1; i++){
char c = charArray[i];
char cNext = charArray[i+1];
char cPrev = charArray[i-1];
if (vowels.contains(c) && !(vowels.contains(cNext) || vowels.contains(cPrev))) {
sb.append(String.format("av%s" , c));
}
else sb.append(c);
}
char cLast = charArray[charArray.length-1];
if (vowels.contains(cLast) && !(vowels.contains(charArray[charArray.length-2]))) {
sb.append(String.format("av%s" , cLast));
}
else sb.append(cLast);
return sb.toString();
}
Works for all the cases I could think of, but probably not the optimal way of doing this.

One approach is to manage the indexes yourself instead of using an enhanced for loop. This allows you to 'skip' over two vowel chunks by checking the next character if it exists. Something like this should work:
int i = 0;
while (i < charArray.length) {
char c = charArray[i];
if (isVowel(c)) {
if (i + i == charArray.length || isVowel(charArray[i+1])) {
sb.append("av");
} else {
i++;
}
}
sb.append(c);
i++;
}
Note that this does not solve for when there are three sequential vowels.

Related

Why does Java function return 1 when given ""

I am new to Java. The purpose of the function is to get a word's vowel count. But when given "" as input it returns 1 instead of 0.
Please explain like i am five why this is happening.
public static int getCount(String str) {
String vowels = "aeiou";
int answer = 0;
String strArray[] = str.split("");
for(String chr : strArray) {
if ((vowels.contains(chr)) & (chr != "")) {
answer += 1;
}
}
return answer;
}
I fixed the code by adding if ((vowels.contains(chr)) & (chr != ""))
But this feels ugly
"".split("") returns {""}. If you want to go over the characters, use one of these:
for (char c : str.toCharArray()) {
if (vowels.indexOf(c) != -1) { ... }
}
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (vowels.indexOf(c) != -1) { ... }
}
I prefer the second, it doesn't create a copy of the string.

How do I handle punctuation in this Pig Latin translator?

The rest of the code is working perfectly but I cannot figure out how to prevent punctuation from being translated.
public class PigLatintranslator
{
public static String translateWord (String word)
{
String lowerCaseWord = word.toLowerCase ();
int pos = -1;
char ch;
for (int i = 0 ; i < lowerCaseWord.length () ; i++)
{
ch = lowerCaseWord.charAt (i);
if (isVowel (ch))
{
pos = i;
break;
}
}
if (pos == 0 && lowerCaseWord.length () != 1) //translates if word starts with vowel
{
return lowerCaseWord + "way"; // Adding "way" to the end of string
}
else if (lowerCaseWord.length () == 1) //Ignores words that are only 1 character
{
return lowerCaseWord;
}
else if (lowerCaseWord.charAt(0) == 'q' && lowerCaseWord.charAt(1) == 'u')//words that start with qu
{
String a = lowerCaseWord.substring (2);
return a + "qu" + "ay";
}
else
{
String a = lowerCaseWord.substring (1);
String b = lowerCaseWord.substring (0,1);
return a + b + "ay"; // Adding "ay" at the end of the extracted words after joining them.
}
}
public static boolean isVowel (char ch) checks for vowel
{
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' || ch == 'y')
{
return true;
}
return false;
}
}
I need the translation to ignore punctuation. For example "Question?" should be translated to "estionquay?" (question mark still in the same position and not translated)
As Andreas said, if the function is expecting only one word, it should be the responsibility of the calling function to ensure there's no full sentence or punctuation being passed to it. With that said, if you require the translator to handle this, you need to find the index of the string where the punctuation or non-letter character occurs. I added in a main method to test the function:
public static void main(String[] args) {
System.out.println(translateWord("QUESTION?"));
}
I added a loop into the qu case to find the punctuation being input, the two checks are to see if the character at position i is inside the range of a - z. The sub-string then only goes to the point where the punctuation is found.
int i;
for (i = 0; i < lowerCaseWord.length(); i++) {
if(lowerCaseWord.charAt(i) > 'z' || lowerCaseWord.charAt(i) < 'a') {
break;
}
}
String a = lowerCaseWord.substring (2, i);
String b = lowerCaseWord.substring(i);
return a + "qu" + "ay" + b;
This may need some tweaking if you're worried about words with hyphens and whatnot but this should put across the basic idea.
Here's the output I received:
$javac PigLatintranslator.java
$java -Xmx128M -Xms16M PigLatintranslator
estionquay?

TitleCaps program will not translate first character in a String correctly (why?)

See if you guys can solve this. I wrote a title caps program in Java, that is a program which can take a string of ASCII characters and make all words (substrings made up of only letters A-Z or a-z) into title case. So the string "##hello!_world$" becomes "##Hello!_World$". But this program refuses to correctly translate non letters at the first indice of the string despite my best efforts to correct it.
public static String LetterCapitalize(String str) {
String newStr = "";
System.out.println(newStr);
for (int i = 0; i < str.length(); i++) {
// if first character is a letter and not uppercase
if (i == 0 && (!isUpperCase(str.charAt(i)))) {
Character m = (char) ((int) str.charAt(i) - 32);
newStr = newStr + m;
} // if first character is a letter and uppercase
else if (i == 0 && (isUpperCase(str.charAt(i)))) {
Character m = str.charAt(i);
newStr = newStr + m;
} // if first character is not a letter
else if (i == 0 && (!isLetter(str.charAt(i)))) {
Character m = str.charAt(i);
newStr = newStr + m + m;
} // if character is first letter in a word
else if (!isLetter(str.charAt(i - 1)) && isLetter(str.charAt(i)) && !isUpperCase(str.charAt(i))) {
Character m = (char) ((int) str.charAt(i) - 32);
newStr = newStr + m;
} // all other
else {
Character m = str.charAt(i);
newStr = newStr + m;
}
}
return newStr;
}
public static boolean isUpperCase(char c) {
boolean isCap;
if (c >= 'A' && c <= 'Z') {
isCap = true;
} else {
isCap = false;
}
return isCap;
}
public static boolean isLetter(char c) {
boolean isLetter;
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
isLetter = true;
} else {
isLetter = false;
}
return isLetter;
}
this line is wrong: if (i == 0 && (!isUpperCase(str.charAt(i)))) { - it assumes it's a lowercase letter. You need to see if it's a lowercase letter. Not all characters that aren't uppercase are letters. So you should have some thing like
if (i==0 && isLetter() && !isUpperCase())
The other way to do it is have the check for it being a letter come first.

Java-How to translate a String to piglatin?

I am writing a pig latin code and I am tripped up by how to get my program to identify where the next vowel in the word is if the first letter in the word is a consonant. Then it moves the first part of the word, up to the first vowel, to the end of the word and prints ay along with it. (ex. trees = eestray)
This is the code I have now
// word is bringing in the string entered from the user
public static void translate(String word) {
String wordCap, pigLatin = "";
char vowels;
int lowest = 0, tempOne, tempTwo, tempThree, tempFour, tempFive;
wordCap = word.toUpperCase();
vowels = wordCap.charAt(0);
if (vowels == 'A' || vowels == 'E' || vowels == 'I' || vowels == 'O' || vowels == 'U') {
word = word + "way";
System.out.println(word);
}
else {
tempOne = wordCap.indexOf('A', 1);
if (lowest > tempOne && tempOne != -1) {
lowest = tempOne;
}
tempTwo = wordCap.indexOf('E', 1);
if (lowest > tempTwo && tempTwo != -1) {
lowest = tempTwo;
}
tempThree = wordCap.indexOf('I', 1);
if (lowest > tempThree && tempThree != -1) {
lowest = tempThree;
}
tempFour = wordCap.indexOf('O', 1);
if (lowest > tempFour && tempFour != -1) {
lowest = tempFour;
}
tempFive = wordCap.indexOf('U', 1);
if (lowest > tempFive && tempFive != -1) {
lowest = tempFive;
}
public static char vowel(String word) {
int start= 0, end= 0;
char vowels;
for (int i = 0; i < word.length(); i++) {
vowels = word.charAt(i);
if (vowels == 'A' || vowels == 'E' || vowels == 'I' || vowels == 'O' || vowels == 'U') {
end = i;
break;
}
}
return (char) end;
}
(in translate method)
for (int i = 0; i<wordCap.length(); i++) {
if (vowel(wordCap.charAt(i))) {
vowels = wordCap.charAt(i);
}
}
The problem now is that the vowel method is not an applicable method type. It says it must be a char?
Let me try to shorten that method for you ;)
Try something like this:
private static final char[] vowels = {'a', 'e', 'i', 'o', 'u'};
public static String translate(String word) {
int start = 0; // start index of word
int firstVowel = 0;
int end = word.length(); // end index of word
for(int i = 0; i < end; i++) { // loop over length of word
char c = Character.toLowerCase(word.charAt(i)); // char of word at i, lower cased
if(Arrays.asList(vowels).contains(c)) { // convert vowels to a list so we can use List.contains() convenience method.
firstVowel = i;
break; // stop looping
}
}
if(start != firstVowel) { // if start is not equal to firstVowel, we caught a vowel.
String startString = word.substring(firstVowel, end);
String endString = word.substring(start, firstVowel) + "ay";
return startString+endString;
}
return word; //couldn't find a vowel, return original
}
What this snippet does, is iterate over every character in the word, storing the index of the first vowel in the firstVowel variable. Then, we get every character from firstVowel to end; and store it in startString. Then, we get every character from start to firstVowel; add "ay", and store it in endString. Finally, we concatenate these strings together and return them, resulting in the desired output.
We can test this with System.out.println(translate("trees"));
EDIT: Without array, as requested:
public static String translate(String word) {
char a = 'a';
char e = 'e';
char i = 'i';
char o = 'o';
char u = 'u';
int start = 0;
int firstVowel = 0;
int end = word.length();
for(int i = 0; i < end; i++) {
char c = Character.toLowerCase(word.charAt(i));
if(c == a || c == e || c == i || c == o || c == u) {
firstVowel = i;
break;
}
}
if(start != firstVowel) {
String startString = word.subString(firstVowel, end);
String endString = word.subString(start, firstVowel) + "ay";
return startString+endString;
}
return word;
}
As you can see, arrays shorten things up quite a bit!
If you're feeling pedantic about the Arrays.asList().contains() call, we could define our own:
public static boolean containsChar(char[] lookIn, char lookFor) {
boolean doesContainChar = false;
for(char c : lookIn) {
if(doesContainChar = c == lookFor)
break;
}
return doesContainChar;
}
You might want to use a for loop to iterate through the letters of each word until it finds a vowel. Example:
String wordCap = word.toUpperCase();
char vowels;
for (int i=0; i<wordCap.length(); i++) {
if (isVowel(wordCap.charAt(i))) {
vowels = wordCap.charAt(i);
break;
}
}
Of course, I only used isVowel() for the sake of keeping the example concise. You'll have to identify it as a vowel the same way you did in your first if statement (or write an isVowel() method yourself).
For modifying the word, you'll also want to declare a variable to hold the index of the vowel. The previous section of code could be added to for this, like so:
String wordCap = word.toUpperCase();
char vowels;
int vowelIndex;
String newWord;
for (int i=0; i<wordCap.length(); i++) {
if (isVowel(wordCap.charAt(i))) {
vowels = wordCap.charAt(i);
vowelIndex = i;
break;
}
}
Then you could reference vowelIndex when modifying the word.
if (vowelIndex == 0) {
newWord = word + "way";
} else {
newWord = word.substring(vowelIndex) + word.substring(0, vowelIndex) + "ay";
}
return word;

Java - Converting the characters in a string array depending on whether or not it's a vowel

The method takes in any name and tests whether a character is a vowel or consonant. If it's a vowel, it makes the character uppercase, if it's a consonant, it makes the character lowercase. Any thoughts? I don't know how to add .toUpperCase and .toLowerCase in the if else statements.
public static void parsing(String name[])
{
String temp = name[0];
int i = 0;
for(i = 0; i < temp.length(); i++)
{
if(temp.charAt(i) == 'a' || temp.charAt(i) == 'A' ||
temp.charAt(i) == 'e' || temp.charAt(i) == 'E' ||
temp.charAt(i) == 'i' || temp.charAt(i) == 'I' ||
temp.charAt(i) == 'o' || temp.charAt(i) == 'O' ||
temp.charAt(i) == 'u' || temp.charAt(i) == 'U')
{
System.out.print(temp.charAt(i).toUpperCase);
}//Obviously wrong but I don't know what to do.
else
{
System.out.print(temp.charAt(i).toLowerCase);
}//Obviously wrong but I don't know what to do.
}
To convert a single character use the methods from the Character class:
System.out.print(Character.toUpperCase(temp.charAt(i)));
System.out.print(Character.toLowerCase(temp.charAt(i)));
Create two final arrays - one with the vowels, the second one with the consonants. Then check, whether the current char in the loop is a vowel or consonant and make the appropriate changes.
Your are hitting your head as String is immutable. Rebuild the resulting string.
A (bit suboptimal) solution is:
public static void parsing(String[] names)
{
for (int i = 0; i < names.length; ++i) {
names[i] = chAngEd(names[i]);
}
}
private static String chAngEd(String s) {
String result = "";
for (int i = 0; i < s.length(); ++i) {
char ch = s.charAt(i);
if (ch == 'a' || ...) {
ch = Character.toUpperCase(ch);
} else {
ch = ...
}
result += ch;
}
return result;
}
public static void parsing(String names[]){
for (int i=0; i<names.length; ++i){
names[i] = capitaliseConsts(names[i]);
}
}
private static String capitaliseConsts(String name){
StringBuilder sb = new StringBuilder();
Character c;
for (int i=0; i<name.length(); ++i){
c = name.charAt(i);
if (c.equalsIgnoreCase('a') ||
c.equalsIgnoreCase('e') ||
c.equalsIgnoreCase('i') ||
c.equalsIgnoreCase('o') ||
c.equalsIgnoreCase('u')){
sb.append(Character.toUpperCase(c));
}
else{
sb.append(Character.toLowerCase(c));
}
}
return sb.toString();
}
String vowelsArray = "aeiuo";
String constantsArray = "uppercase constants";
int stringLength = name.length();
String givenNameCopy = name.ToString();
for(int i = 0; i < stringLength; i++){
if(vowelsArray.contains(givenNameCopy[i]))
then uppercase
else if(constantsArray.contains(givenNameCopy[i]))
then lowercase
else
continue;
hope this helps.

Categories

Resources