2012-11-22 4 views
3

Мое назначение здесь заключалось в создании переводчика-латинского свиньи с использованием рекурсии, который мог бы переводить предложения. Правила были следующими:Полировка моего переводчика-переводчика Pig (Code) (Java)

  1. Если в englishWord нет гласных, то pigLatinWord - это только английский язык + «ay». (Есть десять гласных: «a», «e», «i», «o» и «u» и их прописные символы. «Y» не считается гласным для целей этого присвоения, т.е. мой становится мией, почему становится причиной и т. д.)
  2. Else, если englishWord начинается с гласного, то pigLatinWord - только английский язык + «yay».
  3. В противном случае (если englishWord имеет гласный в нем и еще не начинается с гласной), то pigLatinWord это конец + старт + «ау», где конец и начало определяются следующим образом: -

Пусть начнется все английское слово до (но не включая) его первого гласного. Пусть закончится все английское слово с первого гласного на. Но, если englishWord капитализирован, то капитализируйте конец и «некапитализируйте» начало.

Вот мой код до сих пор (жаль о странном форматировании, мои комментарии получили перепутались):

/*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») но сейчас он не может обрабатывать знаки препинания. В основном, я ищу любые советы или помощь, чтобы мой код обрабатывал пунктуацию или любые способы улучшить мой код (все еще используя рекурсию) в целом.

+1

Одним из улучшений является поместить все ваши гласные в строку константу и использовать 'contains()', чтобы проверить, является ли символ гласным. Кроме того, 'firstVowel (stringA, 0)' можно извлечь в локальную переменную, что еще больше улучшит читаемость. – biziclop

+0

Можете ли вы прояснить часть метода contains()? Я действительно не понимаю, как бы я связал константу строки, contains() и строку, которую я проверяю. Благодарю. – Philip

+1

Я имел в виду что-то вроде этого: 'private static final String VOWELS =" aeiouAEIOU ";', а затем, когда вы проверяете гласные, вы делаете 'private static boolean isVowel (char ch) {return VOWELS.contains (String.valueOf (ch)); } '. Это намного легче читать, чем большой оператор 'if'. – biziclop

ответ

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() есть что-то для упрощения.

Первое сравнение Гласного можно упростить. Один из способов - использовать регулярное выражение. Другой способ заключается в использовании набора:

Предположим, у вас есть что-то вроде этого:

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

Тогда ваша проверка гласный может быть изменен с тех пор, если заявление на что-то вроде:

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; 
} 

Я считаю, просто эти два изменения может почти половины вашего кода, в более читаемом виде.

0

Попробуйте использовать регулярное выражение для соответствия вашим словам. Регулярное выражение [a-zA-Z] + будет соответствовать любой последовательности букв. Я оставлю это как упражнение для вас, как использовать регулярные выражения в java, но это не слишком сложно.

В основном возьмите свою строку, найдите следующий матч. Сохраните позицию последнего символа слова в исходной строке. Обработайте это слово, а затем найдите следующий матч. Теперь возьмите подстроку между последним символом предыдущего совпадения и первым символом текущего совпадения и выведите его как есть, без какой-либо обработки.

Пример: Предположим, у меня есть строка «Привет, мир!».

  • Первый матч будет «Hello», начиная с позиции 0 и заканчивая в позиции 4 (включительно).
  • процесса, что и выход «Ellohay»
  • Найти следующий матч, который был бы «мир», начиная с позиции 7 и заканчивается в положении 11
  • Вывести подстроку между последним символом в предыдущем матче, и первый символ текущего совпадения. Это будет означать от позиции 5 до позиции 6, которая дает строку «,»
  • обрабатывает текущее совпадение и выводит его. Это приведет к выводу «orldway»
  • Попробуйте найти следующий матч. Не найдено совпадений
  • вывести остальную часть строки без какой-либо обработки. Это означает, что от позиции 12 до конца строки. Это дает подстроку "!"

Таким образом, процесс превратит «Привет, мир!». на «Эллохай, орлов!"

Надеется, что это помогает