抛光我的猪拉丁语翻译(代码)(Java)

时间:2012-11-22 22:27:05

标签: java

我的任务是使用递归创建一个猪拉丁语翻译器,可以翻译句子。规则如下:

  1. 如果英语中没有元音,那么pigLatinWord就是englishWord +“ay”。 (有十个元音:'a','e','i','o'和'u',以及它们的大写字母。'y'不被认为是用于此作业的元音,即我变成了我的,为什么变成了为什么,等等。)
  2. 否则,如果englishWord以元音开头,则pigLatinWord只是englishWord +“yay”。
  3. 否则(如果englishWord中有一个元音并且没有以元音开头),则pigLatinWord为end + start +“ay”,其中end和start定义如下: -
  4. 让我们开始全部是英语,直到(但不包括)它的第一个元音。 让我们从第一个元音开始就结束英语。 但是,如果英语资本化,那么资本化结束并且“无资本化”开始。

    到目前为止这是我的代码(抱歉奇怪的格式化,我的评论搞砸了):

        /*Recursively Translate a String (without punctuation or numerical characters) to Pig Latin*/
    
    
    //prep the string for translation and submit it to be translated
    public static String translate(String finished) {
        finished.trim();        //Trim the String of whitespace at the front and end
        finished += " ";        //Because of the recursive method I use, the string must have a
                                //space at the end
        finished = translateSentence(finished); //recursively translate the string
        finished.trim();    //trim the whitespace added earlier
        return finished;    //Return the string
    }
    
    
    //recursively submits each word in the string to the translator, then 
    //returns the translated sentence
    private static String translateSentence(String finished) {
    
    if (finished.length() == 0) {   //the base condition is met when each word in the string
       return finished; //has been sent to the translator (string is empty)
        }
        else {
        return (translateWord(finished.substring(0, finished.indexOf(' ') )) + " "
            + translateSentence(finished.substring(finished.indexOf(' ') + 1)));        
        }
    }
    /*If the base condition is not met, the method returns the first word of the string
     * (translated) and a space, then submits the rest of the 
     * string back to the method.  The first word is defined as the beginning 
     * of the string up until the first space. The rest of the string
     * starts one character after the space.   */
    
    
    
    //Checks the submitted word for vowels and vowel placement, and translates accordingly
    
        private static String translateWord(String stringA) {
        if (stringA.indexOf('a') == -1
        && stringA.indexOf('e') == -1           //Checks for presence of any vowels
        && stringA.indexOf('i') == -1       //if no vowels are found
        && stringA.indexOf('o') == -1       //the word + ay is returned
        && stringA.indexOf('u') == -1
        && stringA.indexOf('A') == -1
        && stringA.indexOf('E') == -1
        && stringA.indexOf('I') == -1
        && stringA.indexOf('O') == -1
        && stringA.indexOf('U') == -1) {
            return stringA + "ay";
        }       
        if (stringA.charAt(0) == 'a'
        ||  stringA.charAt(0) == 'e' //checks if there is a vowel at the start
        ||  stringA.charAt(0) == 'i'//of the string. if there is a vowel
        ||  stringA.charAt(0) == 'o'    //it returns the word + yay
        ||  stringA.charAt(0) == 'u'
        ||  stringA.charAt(0) == 'A'
        ||  stringA.charAt(0) == 'E'
        ||  stringA.charAt(0) == 'I'
        ||  stringA.charAt(0) == 'O'
        ||  stringA.charAt(0) == 'U') {
            return stringA + "yay";
        }       
    /* if the word has a vowel that isn't at the start, the part of the string
    
    
    * before the first vowel is moved to the end of the vowel, and "ay" is added.
    
    
    * However, if the first character in the word is capitalized, the first vowel becomes
    
    
    * uppercase and the former first character in the word becomes lowercase */
        else {
            if (Character.isUpperCase(stringA.charAt(0))) {
                return Character.toUpperCase(stringA.charAt(firstVowel(stringA, 0))) 
                + stringA.substring(firstVowel(stringA, 0) + 1, stringA.length())
                + Character.toLowerCase(stringA.charAt(0))
                + stringA.substring(1, firstVowel(stringA, 0)) + "ay";
            }
            else {
            return stringA.substring(firstVowel(stringA, 0), stringA.length()) 
            + stringA.substring(0, firstVowel(stringA, 0)) + "ay";
            }
        }
    }
    
    
    
    //Recursively determines the index number of the first vowel in a given word
    //0 must always be submitted as int x
    public static int firstVowel(String stringA, int x) {
        if (x > stringA.length() - 1) {     //if the index number becomes greater than the length
            return -1;      //of the string, -1 (no vowels) is returned
        }
        if (stringA.charAt(x) == 'a' 
            || stringA.charAt(x) == 'e'     //the base condition is met when the character
            || stringA.charAt(x) == 'i'     //at the current index number is a vowel
            || stringA.charAt(x) == 'o'     //and the index number is returned
            || stringA.charAt(x) == 'u' 
            || stringA.charAt(x) == 'A' 
            || stringA.charAt(x) == 'E' 
            || stringA.charAt(x) == 'I' 
            || stringA.charAt(x) == 'O' 
            || stringA.charAt(x) == 'U') {
            return x;
        }
        else {
            return firstVowel(stringA, x + 1);  //otherwise, the string and the index number
        }                                       // + 1 are submitted back to the method
    }
    

    这给了我想要的输出(“为什么你好”变成“Whyay ellohay erethay”) 但是现在它无法处理标点符号。基本上我正在寻找的是任何提示或帮助我的代码处理标点符号,或任何方法来改进我的代码(仍然使用递归)。

2 个答案:

答案 0 :(得分:2)

@Cedric给出了一个很好的建议,即在执行处理时使用Regex。

我在这里给出一些其他指示。

首先,我相信您可以更好地重复使用firstVowel方法。

您的translateWord可以大大简化为(我跳过大写处理以便于理解):

private static String translateWord(String s) {
    int firstVowelIndex = firstVowel(s);
    if (firstVowel < 0) { // no Vowel
        return s + "ay";
    } else if (firstVowel == 0) {  // start with Vowel
        return s + "yay";
    } else {
        return s.substring(firstVowelIndex) + s.substring(0, firstVowelIndex) + "ay";
    }
}

您的firstVowel()也有一些简化。

首先,可以简化元音的比较。一种方法是使用正则表达式。另一种方法是使用Set:

假设你有类似的东西:

static Set<Character> vowels = new HashSet<Character>(
        Arrays.asList('a','e','i','o','u','A','E','I','O','U'));

然后您的元音检查可以从长if语句更改为:

if (vowels.contains(c)) {...}

其次,您可能会以递归方式故意编写firstVowel()以进行练习。但是,在我看来,如果以循环的形式编写该方法,则该方法更容易阅读:

private static int firstVowel(String s) {
    int index = -1;
    for (int i = 0; i < s.length; ++i ) {
        if (isVowel(s.charAt(i)) {
            index = i;
            break;
        }
    }
    return index;
}

我相信只需这两个更改就可以以更易读的方式将代码的一半改为。

答案 1 :(得分:0)

尝试使用正则表达式来匹配您的单词。正则表达式[a-zA-Z] +将匹配任何同时的字母序列。我将把它作为练习留给你如何在java中使用正则表达式,但它并不太难。

基本上拿你的字符串,找到下一个匹配。将单词的最后一个字符的位置存储在原始字符串中。处理那个单词,然后找到下一个匹配。现在取上一个匹配的最后一个字符和当前匹配的第一个字符之间的子字符串,并按原样输出,不进行任何处理。

示例:假设我有字符串“Hello,world!”

  • 第一场比赛将是“Hello”,从第0位开始,到第4位(包括第4位)结束。
  • 处理并输出“Ellohay”
  • 找到下一场比赛,从第7位开始,到第11位结束
  • 输出上一个匹配的最后一个字符与当前匹配的第一个字符之间的子字符串。这意味着从位置5到位置6,它给出字符串“,”
  • 处理当前匹配并输出。这将输出“orldway”
  • 尝试找到下一场比赛。现在找不到匹配项
  • 输出字符串的其余部分而不进行任何处理。这意味着从位置12到字符串的结尾。这给出了子串“!”

通过这种方式,这个过程将改变“Hello,world!” “Ellohay,orldway!”

希望这有帮助