una - Java-Escribir un contador de sílabas basado en especificaciones
separar una palabra en letras java (7)
Uno de los problemas podría ser que llame al método de caso de amante en la entrada, pero no lo asigna.
Entonces si cambias
word.toLowerCase();
a
word = word.toLowerCase();
ayudará con seguridad.
Especificación para una sílaba:
Cada grupo de vocales adyacentes (a, e, i, o, u, y) cuenta como una sílaba (por ejemplo, la "ea" en "real" contribuye con una sílaba, pero la "e ... a" en "real" "cuenta como dos sílabas). Sin embargo, una "e" al final de una palabra no cuenta como una sílaba. Además, cada palabra tiene al menos una sílaba, incluso si las reglas anteriores dan un recuento de cero.
Mi método countSyllables:
public int countSyllables(String word) {
int count = 0;
word = word.toLowerCase();
for (int i = 0; i < word.length(); i++) {
if (word.charAt(i) == ''/"'' || word.charAt(i) == ''/''' || word.charAt(i) == ''-'' || word.charAt(i) == '','' || word.charAt(i) == '')'' || word.charAt(i) == ''('') {
word = word.substring(0,i)+word.substring(i+1, word.length());
}
}
boolean isPrevVowel = false;
for (int j = 0; j < word.length(); j++) {
if (word.contains("a") || word.contains("e") || word.contains("i") || word.contains("o") || word.contains("u")) {
if (isVowel(word.charAt(j)) && !((word.charAt(j) == ''e'') && (j == word.length()-1))) {
if (isPrevVowel == false) {
count++;
isPrevVowel = true;
}
} else {
isPrevVowel = false;
}
} else {
count++;
break;
}
}
return count;
}
El método isVowel que determina si una letra es una vocal:
public boolean isVowel(char c) {
if (c == ''a'' || c == ''e'' || c == ''i'' || c == ''o'' || c == ''u'') {
return true;
} else {
return false;
}
}
Según un colega, esto debería dar como resultado 528 sílabas cuando se usa en este texto , pero parece que puedo igualarlo y no sé cuál de nosotros está en lo correcto. Por favor, ayúdame a desarrollar mi método en el algoritmo correcto o ayudar a demostrar que esto es correcto. Gracias.
Esto debería ser fácilmente factible con algunos Regex:
Pattern p = Pattern.compile("[aeiouy]+?/w*?[^e]");
String[] result = p.split(WHAT_EVER_THE_INPUT_IS);
result.length
Tenga en cuenta que no está probado.
No es una respuesta directa (y le daría una si pensase que era constructiva, mi recuento es de aproximadamente 238 en el último intento) pero le daré algunos consejos que serán fundamentales para crear la respuesta:
- Divida su problema: lea líneas, luego divida las líneas en palabras, luego cuente las sílabas para cada palabra. Afterwords, cuentelas para todas las líneas.
- Piense en el orden de las cosas: primero encuentre todas las sílabas y cuente cada una "caminando" a través de la palabra. Factor en los casos especiales después.
- Durante el diseño, use un depurador para recorrer su código. Es probable que cometas errores comunes como el método
toUpperCase()
. Es mejor encontrar esos errores, nadie creará un código perfecto la primera vez. - Imprimir en la consola (los usuarios avanzados usan un registro y mantienen las líneas de registro silenciadas en el programa final). Asegúrese de marcar la
println
usando comentarios y eliminarlos de la implementación final. Imprima cosas como números de línea y recuentos de sílabas para que pueda compararlos visualmente con el texto. - Si ha avanzado un poco, puede usar
Matcher.find
(expresiones regulares) usando unPattern
para encontrar las sílabas. Las expresiones regulares son bestias difíciles de dominar. Un error común es hacer que hagan demasiado de una vez.
De esta forma, puede escanear rápidamente el texto. Una de las cosas que descubrirá rápidamente es que tendrá que lidiar con los números en el texto. Por lo tanto, debe verificar si una palabra es en realidad una palabra; de lo contrario, según sus reglas, tendrá al menos una sola sílaba.
Si tiene la sensación de que está repitiendo cosas, como los isVowel
y String.contains()
que usan el mismo conjunto de caracteres, probablemente esté haciendo algo mal. La repetición en el código fuente es olor a código.
Usando expresiones regulares, conté alrededor de 238 (en el cuarto intento), pero realmente no he verificado todas y cada una de las sílabas (por supuesto).
1 14
2 17
3 17
4 15
5 15
6 14
7 16
8 19
9 17
10 17
11 16
12 19
13 18
14 15
15 18
16 15
17 16
18 17
19 16
20 17
21 17
22 19
23 17
24 16
25 17
26 17
27 16
28 17
29 15
30 17
31 19
32 23
33 0
--- total ---
538
Le sugiero encarecidamente que utilice la API String de Java a su máxima capacidad. Por ejemplo, considere String.split (String regex):
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split%28java.lang.String%29
Esto toma una cadena y una expresión regular, luego regresa una matriz de todas las subcadenas, usando su expresión regular como un delímetro. Si haces que tu expresión regular coincida con todas las consonantes o espacios en blanco, terminarás con una matriz de cadenas que están vacías (y por lo tanto no representan una consonante) o una secuencia de vocales (que sí representan una consonante). Cuente el último y tendrá una solución.
Otra alternativa que también aprovecha la API String y las expresiones regulares es replaceAll:
En este caso, quieres una expresión regular que adopte la forma [algo opcional que no sea una vocal] [una o más vocales] [algo opcional que no sea una vocal]. Ejecute esta expresión regular en su String y reemplácela con un solo carácter (por ejemplo, "1"). El resultado final es que cada sílaba será reemplazada por un solo carácter. Entonces todo lo que necesitas hacer es String.length () y sabrás cuántas sílabas tienes.
Dependiendo de los requisitos de su solución, estos pueden no funcionar. Si esta es una pregunta de tarea relacionada con el diseño del algoritmo, esta no es la respuesta preferida, pero tiene el beneficio de ser conciso y hace un buen uso de las API de Java incorporadas (y por lo tanto altamente optimizadas).
Acabo de inventar una nueva forma de contar sílabas en Java.
Mi nueva biblioteca, The Lawrence Style Checker, se puede ver aquí: https://github.com/troywatson/Lawrence-Style-Checker
Conté tus sílabas para cada palabra usando mi programa y mostré los resultados aquí: http://pastebin.com/LyiBTcbb
Con el método de mi diccionario de contar sílabas obtuve: 528 sílabas en total.
Este es el número exacto que el interrogador dio del número correcto de sílabas. Sin embargo, todavía impugno este número por las razones que se describen a continuación:
Tasa de ataque: 99.4% correcto
Palabras incorrectas: 2/337 palabras
Palabras incorrectas y recuentos de sílabas incorrectos: {Resinous: 4, aardwolf: 3}
Aquí está mi código:
Lawrence lawrence = new Lawrence();
// Turn the text into an array of sentences.
String sentences = ""
String[] sentences2 = sentences.split("(?<=[a-z])//.//s+");
int count = 0;
for (String sentence : sentences2) {
sentence = sentence.replace("-", " "); // split double words
for (String word : sentence.split(" ")) {
// Get rid of punctuation marks and spaces.
word = lawrence.cleanWord(word);
// If the word is null, skip it.
if (word.length() < 1)
continue;
// Print out the word and it''s syllable on one line.
System.out.print(word + ",");
System.out.println(lawrence.getSyllable(word));
count += lawrence.getSyllable(word);
}
}
System.out.println(count);
bam!
Esta es mi implementación para contar sílabas
protected int countSyllables(String word)
{
// getNumSyllables method in BasicDocument (module 1) and
// EfficientDocument (module 2).
int syllables = 0;
word = word.toLowerCase();
if(word.contains("the ")){
syllables ++;
}
String[] split = word.split("e!$|e[?]$|e,|e |e[),]|e$");
ArrayList<String> tokens = new ArrayList<String>();
Pattern tokSplitter = Pattern.compile("[aeiouy]+");
for (int i = 0; i < split.length; i++) {
String s = split[i];
Matcher m = tokSplitter.matcher(s);
while (m.find()) {
tokens.add(m.group());
}
}
syllables += tokens.size();
return syllables;
}
Funciona bien para mí.
private static int countSyllables(String word)
{
//System.out.print("Counting syllables in " + word + "...");
int numSyllables = 0;
boolean newSyllable = true;
String vowels = "aeiouy";
char[] cArray = word.toCharArray();
for (int i = 0; i < cArray.length; i++)
{
if (i == cArray.length-1 && Character.toLowerCase(cArray[i]) == ''e''
&& newSyllable && numSyllables > 0) {
numSyllables--;
}
if (newSyllable && vowels.indexOf(Character.toLowerCase(cArray[i])) >= 0) {
newSyllable = false;
numSyllables++;
}
else if (vowels.indexOf(Character.toLowerCase(cArray[i])) < 0) {
newSyllable = true;
}
}
//System.out.println( "found " + numSyllables);
return numSyllables;
}
Se puede encontrar otra implementación en el siguiente enlace pastebin: https://pastebin.com/q6rdyaEd