Trouble converting normal sentences to pig latin - java

I'm trying to convert a sentence to pig latin but can't seem to get the correct output to work. For example the input
the rain in spain stays mainly in the plain yields an output of ethay ethay ethay with my current code whereas the expected output is ethay ainray inay ainspay aysstay ainlymay inay ethay ainplay
For those unfamiliar, the basic rules of pig latin are:
If the word begins with a consonant, take the beginning consonants up until the first vowel and move them to the end of the word. Then append ay at the very end. (so cricket would become icketcray)
If the word begins with a vowel, simply add ay to the end. (apple would become appleay)
If y is the first letter in the word, treat it as a consonant, otherwise it is used as a vowel. (young would become oungyay and system would become ystemsay)
My code is as follows:
import java.util.Scanner;
public class PigLatin{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String line = scan.next();
String piglatin = translateSentence(line);
System.out.println(piglatin);
}
public static String translateSentence(String line){
for (int i =0; i < line.length(); i++ ) {
char c = line.charAt(i);
//for loop to analyze each word
if (Character.isAlphabetic(c)) {
//if (i <='a' || i<='A' || i>='z' || i>='Z'){
String piglatin = translateword(line);
return piglatin;
}
}
return line;
}
public static String translateword(String line) {
Scanner scan = new Scanner(System.in);
int position = firstVowel(line);
String words = "";
String output = "";
for(int i = 0; i<line.length();i++){
words = "";
if (firstVowel(line) == 0) {
words = line + "-way";
} else if (firstVowel(line) == -1) {
words = line + "";
} else {
String first = line.substring(position);
String second = line.substring(0,position) + "ay";
words = first + second;
}
output = output + " " + words;
//words = "";
}
return output;
}
public static int firstVowel(String line) {
for (int i = 0; i < line.length(); i++) {
if (line.charAt(i) == 'a' || line.charAt(i) == 'e'
|| line.charAt(i) == 'i' || line.charAt(i) == 'o'
|| line.charAt(i) == 'u') {
return i;
}
}
return -1;
}
}
Any help is greatly appreciated, thank you.

first write a separate function to get list of words from line
public String[] getWords(String line) {
String list[]=new String[100];
int j=0;
int end;
end=line.indexOf(' ');
while (end!=-1) {
list[j]=line.substring(0, end);
line=line.substring(end+1,line.length());
j++;
end=line.indexOf(' ');
}
list[j]=line.substring(0,line.length());
return list;
}
then modify your translate line to call translate word multiple times, each time pass a single word.
Assuming your translateWord() returns a single correctly translated word. translateLine change in the following way:
if (Character.isAlphabetic(c)) {
String wordList[]=getWords(line);
String piglatin="";
int i=0;
while(!line[i].equals("")) {
piglatin = piglatin+translateword(word[i]);
i++;
}
return piglatin;
}

Related

Find word in User Content without using .split() or StringTokenizer

I'm working on a program that ask the user to input a phrase and an integer. The integer is used to identify which word will be return from the phrase. For example, if they enter 5, the program should return to the user the fifth word in the sentence.
System.out.println("Your word is: " +combineString(phrase,numWord));
This is my work so far, there is a main to output,
public static String combineString(String newPhrase, int newNum) {
int countWords = 0;
String word = "";
//words count. I'll +1 everytime using countWord the match the amount of words
for(int i=0; i< newPhrase.length(); i++) {
if(newPhrase.charAt(i) == ' ') {
countWords++;
}
}
//return the last word. Ex: 15 words in a phrase if user pick the 18th word it will return the 15th word.
if(countWords+1 < newNum || countWords+1 <= newNum) {
word += newPhrase.substring(newPhrase.lastIndexOf(' ')+1, newPhrase.length()-1);
}
else if(newNum <=0) { //return null if the user pick 0 or less than 0
word += null;
}
return word;
And I was thinking a lot on how to work on the middle part and my thought are if the user pick numWord = 5, then in order to return the fifth word in that sentence, I'm gonna need to use "newPhrase.substring(space 4th +1, space 5th)". And this is where I stuck because I don't know how to start, and how to get to space 4th.
public static String combineString(String newPhrase, int newNum) {
if(newNum<=0)
return null;
String word = "";
String [] match = new String[newNum];
int j =0;
for(int i=0; i< newPhrase.length(); i++) {
word = word + newPhrase.charAt(i);
if(newPhrase.charAt(i) == ' ') {
match[j] = word;
if(j+1 == newNum) {
return word; // returns the specified word
}
j++;
word = "";
}
}
return word; //returns last word
}
This code should work for you. If that's the case accept the answer.
If you want to go really low level, then you can go lower than subString and operate on single characters. This way its easy to skip other characters than blank. Its also a step towards the way regular expression get executed by transforming them to finite state automatons.
enum ScanState {WHITESPACE, WORD}
private final static Set<Character> whitespace = new HashSet<>(Arrays.asList('"', ',', '.', '?', '!', '-', ';', ' '));
#Test
public void testTokenize() {
char[] text = "No, it's been \"yes?\", and not \"no!\" - hasn't it?".toCharArray();
List<String> expected = Arrays.asList("No", "it's", "been", "yes", "and", "not", "no", "hasn't", "it");
assertEquals(expected, tokenize(text));
}
private List<String> tokenize(char[] text) {
List<String> result = new ArrayList<String>();
char[] word = new char[256];
int maxLetter = 0;
ScanState prevState = ScanState.WHITESPACE;
for (char currentChar : text) {
ScanState currState = whitespace.contains(currentChar) ? ScanState.WHITESPACE : ScanState.WORD;
if (prevState == ScanState.WORD && currState == ScanState.WORD) {
word[maxLetter++] = currentChar;
}
if (prevState == ScanState.WORD && currState == ScanState.WHITESPACE) {
word[maxLetter++] = currentChar;
result.add(String.valueOf(word, 0, maxLetter - 1));
}
if (prevState == ScanState.WHITESPACE && currState == ScanState.WORD) {
maxLetter = 0;
word[maxLetter++] = currentChar;
}
prevState = currState;
}
return result;
}

pig latin-like program - issues with vowels

I'm writing a program that has two rules:
1. If the first character of the word is a vowel, then move it to the end of the word.
2. If the first character of the word is a consonant, then move it to the end of the word and append 'ae'.
import java.util.Scanner;
public class Program5 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
System.out.print("Please enter a sentence: ");
String english = scanner.nextLine();
String piggy = piggyEnglish(english);
System.out.print("Translated: " + piggy);
}
private static String piggyEnglish(String s) {
String piggy = "";
int i = 0;
while (i<s.length()) {
while (i<s.length() && !isLetter(s.charAt(i))) {
piggy = piggy + s.charAt(i);
i++;
}
if (i>=s.length()) break;
int begin = i;
while (i<s.length() && isLetter(s.charAt(i))) {
i++;
}
int end = i;
piggy = piggy + piggyWord(s.substring(begin, end));
}
return piggy;
}
private static boolean beginsWithVowel(String word){
String vowels = "aeiou";
char letter = word.charAt(0);
return (vowels.indexOf(letter) != -1);
}
private static boolean isLetter(char c) {
return ( (c >='A' && c <='Z') || (c >='a' && c <='z') );
}
private static String piggyWord(String word) {
int split = firstVowel(word);
if(beginsWithVowel(word)) {
return word.substring(split) + word.substring(0, split);
} else {
return word.substring(split) + word.substring(0, split)+"ae";
}
}
private static int firstVowel(String word) {
word = word.toLowerCase();
for (int i=0; i<word.length(); i++)
if (word.charAt(i)=='a' || word.charAt(i)=='e' ||
word.charAt(i)=='i' || word.charAt(i)=='o' ||
word.charAt(i)=='u')
return i;
return 0;
}
}
The following is the expected output:
Please enter a sentence: today is a beautiful day
Translated: odaytae si a eautifulbae aydae
However, this is what I'm getting:
Please enter a sentence: today is a beautiful day
Translated: odaytae is a eautifulbae aydae
Basically, it doesn't translate any words that start with a vowel. I think the problem stems from the piggyWord method, but I'm not certain. Can I get any pointers on how to fix this?
The error lies in the piggyWord function:
private static String piggyWord(String word) {
int split = firstVowel(word);
if(beginsWithVowel(word)) {
return word.substring(split + 1) + word.substring(0, split + 1); //Since vowel is in 1st place, substring(0,0) returns empty string.
} else {
return word.substring(split) + word.substring(0, split)+"ae";
}
}
Based on your rules, you don't need the method firstVowel() to get the index of the first vow in a word because you only need to know whether the first character in the word is a vow or not.
So simply change you piggyWord method to the following will solve your problem:
private static String piggyWord(String word) {
if(beginsWithVowel(word)) {
return word.substring(1) + word.substring(0, 1);
} else {
return word.substring(1) + word.substring(0, 1)+"ae";
}
}
Or more simply:
private static String piggyWord(String word) {
String result = word.substring(1) + word.substring(0, 1);
return beginsWithVowel(word) ? result : result + "ae";
}
Because you always have to move the first character of a word to the end, the only thing is that whether you need to append an extra "ae" in the end or not.
If only the first letter is concerned than in "firstVowel" you can return 1 if vowel is at first position.
private static int firstVowel(String word) {
word = word.toLowerCase();
for (int i=0; i<word.length(); i++)
if (word.charAt(i)=='a' || word.charAt(i)=='e' ||
word.charAt(i)=='i' || word.charAt(i)=='o' ||
word.charAt(i)=='u')
return 1;
return 0;
}

how to capitalize first letter after period in each sentence using java?

I'm currently learning on how to manipulate strings and i think it'll take awhile for me to get used to it. I wanted to know how to capitalize a letter after a period in each sentence.
The output is like this:
Enter sentences: i am happy. this is genius.
Capitalized: I am happy. This is genius.
I have tried creating my own code but its not working, feel free to correct and change it. Here is my code:
package Test;
import java.util.Scanner;
public class TestMain {
public static void main(String[]args) {
String sentence = getSentence();
int position = sentence.indexOf(".");
while (position != -1) {
position = sentence.indexOf(".", position + 1);
sentence = Character.toUpperCase(sentence.charAt(position)) + sentence.substring(position + 1);
System.out.println("Capitalized: " + sentence);
}
}
public static String getSentence() {
Scanner hold = new Scanner(System.in);
String sent;
System.out.print("Enter sentences:");
sent = hold.nextLine();
return sent;
}
}
The tricky part is how am i gonna capitalize a letter after the period(".")? I don't have a lot of string manipulation knowledge so I'm really stuck in this area.
Try this:
package Test;
import java.util.Scanner;
public class TestMain {
public static void main(String[]args){
String sentence = getSentence();
StringBuilder result = new StringBuilder(sentence.length());
//First one is capital!
boolean capitalize = true;
//Go through all the characters in the sentence.
for(int i = 0; i < sentence.length(); i++) {
//Get current char
char c = sentence.charAt(i);
//If it's period then set next one to capital
if(c == '.') {
capitalize = true;
}
//If it's alphabetic character...
else if(capitalize && Character.isAlphabetic(c)) {
//...we turn it to uppercase
c = Character.toUpperCase(c);
//Don't capitalize next characters
capitalize = false;
}
//Accumulate in result
result.append(c);
}
System.out.println(result);
}
public static String getSentence(){
Scanner hold = new Scanner(System.in);
String sent;
System.out.print("Enter sentences:");
sent = hold.nextLine();
return sent;
}
}
What this is doing it advancing sequentially through all of the characters in the string and keeping state of when the next character needs to be capitalized.
Follow the comments for a deeper exaplanations.
You could implement a state machine:
It starts in the capitalize state, as each character is read it emits it and then decides what state to go to next.
As there are just two states, the state can be stored in a boolean.
public static String capitalizeSentence(String sentence) {
StringBuilder result = new StringBuilder();
boolean capitalize = true; //state
for(char c : sentence.toCharArray()) {
if (capitalize) {
//this is the capitalize state
result.append(Character.toUpperCase(c));
if (!Character.isWhitespace(c) && c != '.') {
capitalize = false; //change state
}
} else {
//this is the don't capitalize state
result.append(c);
if (c == '.') {
capitalize = true; //change state
}
}
}
return result.toString();
}
Here is solution with regular expressions:
public static void main(String[]args) {
String sentence = getSentence();
Pattern pattern = Pattern.compile("^\\W*([a-zA-Z])|\\.\\W*([a-zA-Z])");
Matcher matcher = pattern.matcher(sentence);
StringBuffer stringBuffer = new StringBuffer("Capitalized: ");
while (matcher.find()) {
matcher.appendReplacement(stringBuffer, matcher.group(0).toUpperCase());
}
matcher.appendTail(stringBuffer);
System.out.println(stringBuffer.toString());
}
Seems like your prof is repeating his assignments. This has already been asked:
Capitalize first word of a sentence in a string with multiple sentences
Use a pre-existing lib:
http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/text/WordUtils.html#capitalize(java.lang.String,%20char...)
and guava
public static void main(String[] args) {
String sentences = "i am happy. this is genius.";
Iterable<String> strings = Splitter.on('.').split(sentences);
List<String> capStrings = FluentIterable.from(strings)
.transform(new Function<String, String>()
{
#Override
public String apply(String input){
return WordUtils.capitalize(input);
}
}).toList();
System.out.println(Joiner.on('.').join(capStrings));
}
Just use
org.apache.commons.lang3.text.WordUtils.capitalizeFully(sentence);
You can use below code to capitalize first letter after period in
each sentence.
String input = "i am happy. this is genius.";
String arr[] = input.split("\\.");
for (int i = 0; i < arr.length; i++) {
System.out.print(Character.toUpperCase(arr[i].trim().
charAt(0)) + arr[i].trim().substring(1) + ". ");
}
I'd go for regex as it is fast to use:
Split your string by ".":
String[] split = input.split("\\.");
Then capitalize the first letter of the resulting substrings and reunite to result string. (Be careful for spaces between periods and letters, maybe split by "\. "):
String result = "";
for (int i=0; i < split.length; i++) {
result += Character.toUpperCase(split[i].trim());
}
System.out.println(result);
Should do it.
The correct method to do it with core java using regex will be
String sentence = "i am happy. this is genius.";
Pattern pattern = Pattern.compile("[^\\.]*\\.\\s*");
Matcher matcher = pattern.matcher(sentence);
String capitalized = "", match;
while(matcher.find()){
match = matcher.group();
capitalized += Character.toUpperCase(match.charAt(0)) + match.substring(1);
}
System.out.println(capitalized);
Try this:
1. Capitalize the first letter.
2. If the character is '.' set the flag true so that you can capitalize the next character.
public static String capitalizeSentence(String str)
{
if(str.length()>0)
{
char arr[] = str.toCharArray();
boolean flag = true;
for (int i = 0; i < str.length(); i++)
{
if (flag)
{
if (arr[i] >= 97 && arr[i] <= 122)
{
arr[i] = (char) (arr[i] - 32);
flag = false;
}
} else
{
if (arr[i] == '.')
flag = true;
}
}
return new String(arr);
}
return str;
}

Reverse every 2nd word of a sentence

I am trying to reverse every 2nd words of every single sentence like
If a given string is :
My name is xyz
The desired output should be :
My eman is zyx
My current output is:
Ym eman s1 zyx
I am not able to achieve my desired output.Don't know what I am doing wrong here
Here is my code
char[] sentence = " Hi my name is person!".toCharArray();
System.out.println(ReverseSentence(sentence));
}
private static char[] ReverseSentence(char[] sentence)
{
//Given: "Hi my name is person!"
//produce: "iH ym eman si !nosrep"
if(sentence == null) return null;
if(sentence.length == 1) return sentence;
int startPosition=0;
int counter = 0;
int sentenceLength = sentence.length-1;
//Solution handles any amount of spaces before, between words etc...
while(counter <= sentenceLength)
{
if(sentence[counter] == ' ' && startPosition != -1 || sentenceLength == counter) //Have passed over a word so upon encountering a space or end of string reverse word
{
//swap from startPos to counter - 1
//set start position to -1 and increment counter
int begin = startPosition;
int end;
if(sentenceLength == counter)
{
end = counter;
}
else
end = counter -1;
char tmp;
//Reverse characters
while(end >= begin){
tmp = sentence[begin];
sentence[begin] = sentence[end];
sentence[end] = tmp;
end--; begin++;
}
startPosition = -1; //flag used to indicate we have no encountered a character of a string
}
else if(sentence[counter] !=' ' && startPosition == -1) //first time you encounter a letter in a word set the start position
{
startPosition = counter;
}
counter++;
}
return sentence;
}
If you want to reverse the alternate word you can try something like splitting the whole String into words delimited by whitespaces and apply StringBuilder reverse() on every second word like :-
String s = "My name is xyz";
String[] wordsArr = s.split(" "); // broke string into array delimited by " " whitespace
StringBuilder sb = new StringBuilder();
for(int i = 0 ; i< wordsArr.length; i++){ // loop over array length
if(i%2 == 0) // if 1st word, 3rd word, 5th word..and so on words
sb.append(wordsArr[i]); // add the word as it is
else sb.append(new StringBuilder(wordsArr[i]).reverse()); // else use StringBuilder revrese() to reverse it
sb.append(" ");// add a whitespace in between words
}
System.out.println(sb.toString().trim()); //remove extra whitespace from the end and convert StringBuilder to String
Output :- My eman is zyx
You can solve your problem vary easy way! Just use a flag variable which will indicate the even or odd position, more precisely whether any word will gonna be reversed or not!
Look at the following modification I made in your code, just added three extra line:
private static boolean flag = true;// added a variable flag to check if we reverse the word or not.
private static char[] ReverseSentence(char[] sentence)
{
//Given: "Hi my name is person!"
//produce: "iH ym eman si !nosrep"
if(sentence == null) return null;
if(sentence.length == 1) return sentence;
int startPosition=0;
int counter = 0;
int sentenceLength = sentence.length-1;
//Solution handles any amount of spaces before, between words etc...
while(counter <= sentenceLength)
{
if(sentence[counter] == ' ' && startPosition != -1 || sentenceLength == counter) //Have passed over a word so upon encountering a space or end of string reverse word
{
flag = !flag; // first time (odd position) we are not going to reverse!
//swap from startPos to counter - 1
//set start position to -1 and increment counter
int begin = startPosition;
int end;
if(sentenceLength == counter)
{
end = counter;
}
else
end = counter -1;
char tmp;
//Reverse characters
while(end >= begin & flag){ //lets see whether we are going to reverse or not
tmp = sentence[begin];
sentence[begin] = sentence[end];
sentence[end] = tmp;
end--; begin++;
}
startPosition = -1; //flag used to indicate we have no encountered a character of a string
}
else if(sentence[counter] !=' ' && startPosition == -1) //first time you encounter a letter in a word set the start position
{
startPosition = counter;
}
counter++;
}
return sentence;
}
Input
My name is xyz
Output:
My eman is zyx
The following code does this "special reverse" which reverses any other word in the sentence:
public static void main(String[] args) {
String sentence = "My name is xyz";
System.out.println(specialReverse(sentence)); // My eman is zyx
}
private static String specialReverse(String sentence) {
String result = "";
String[] words = sentence.split(" ");
// we'll reverse only every second word according to even/odd index
for (int i = 0; i < words.length; i++) {
if (i % 2 == 1) {
result += " " + reverse(words[i]);
} else {
result += " " + words[i];
}
}
return result;
}
// easiest way to reverse a string in Java in a "one-liner"
private static String reverse(String word) {
return new StringBuilder(word).reverse().toString();
}
Just for completeness here's Java-8 solution:
public static String reverseSentence(String input) {
String[] words = input.split(" ");
return IntStream.range(0, words.length)
.mapToObj( i -> i % 2 == 0 ? words[i] :
new StringBuilder(words[i]).reverse().toString())
.collect(Collectors.joining(" "));
}
reverseSentence("My name is xyz"); // -> My eman is zyx
package com.eg.str;
// Without using StringBuilder
// INPUT: "Java is very cool prog lang"
// OUTPUT: Java si very looc prog gnal
public class StrRev {
public void reverse(String str) {
String[] tokens = str.split(" ");
String result = "";
String k = "";
for(int i=0; i<tokens.length; i++) {
if(i%2 == 0)
System.out.print(" " + tokens[i] + " ");
else
result = tokens[i];
for (int j = result.length()-1; j >= 0; j--) {
k = "" + result.charAt(j);
System.out.print(k);
}
result = "";
}
}
public static void main(String[] args) {
StrRev obj = new StrRev();
obj.reverse("Java is very cool prog lang");
}
}
//reverse second word of sentence in java
public class ReverseSecondWord {
public static void main(String[] args) {
String s="hello how are you?";
String str[]=s.split(" ");
String rev="";
for(int i=0;i<str[1].length();i++)
{
char ch=str[1].charAt(i);
rev=ch+rev;
}
str[1]=rev;
for(int i=0;i<str.length;i++)
{
System.out.print(str[i]+" ");
}
}
}

Translating phrases into pig latin with string

I am currently coding a pig latin translator that breaks down strings into words and then translate them. If any of the first four letters of a word are consonsants, it will move those letters to the back and add an "ay." If the word begins with a vowel, add "way" to the end of the word.
Apparently my pig latin translator code does not output a translated string, but instead it gives me original english words broken down in several different parts. I am a little stuck on what to go next, if anyone can help me diagnose the problem then it will be great. Thanks!
public class WL10Driver {
public String convertToPig(String english){
String pigLatin = "";
int pigLatinWord = 0;
String vowel = "[aeiouAEIOU]";
for(int i = 0; i<english.length(); i++){
char let = english.charAt(i);
int ind = vowel.indexOf(let);
if(ind > -1){
if(i == 0){
return english+"yay";
}
else{
String start = english.substring(0,i);
String end = english.substring(i);
return end+start+"ay";
}
}
}
return english+"ay";
}
}
It seems like the problem is with the calling method. I made it show JOptionPane.showMessageDialog(null,english);.
What should I make JOptionPane show instead?
boolean isVowel(char ch) {
return "aeiouAEIOU".contains("" + ch);
}
public String convertToPig(String english) {
if (english == null) return null;
for (int i = 0; i < Math.min(english.length(), 4); i++) {
char ch = english.charAt(i);
if (i == 0 && isVowel(ch)) return english + "way";
if (!isVowel(ch)) {
String tmp = "";
if (i < english.length() - 1) tmp = english.substring(i + 1);
return english.substring(0, i) + tmp + ch + "ay";
}
}
return english;
}

Categories