Frustracion

Iniciado por ronbay, 17 Junio 2021, 02:06 AM

0 Miembros y 1 Visitante están viendo este tema.

ronbay

BUENAS GENTE.
AYUDA CON RECURSIVIDAD POR FAVOR.
tengo un ejercicio que tiene que contar cuantas palabras hay en una cadena.
lo he tratado de hacer de muchas maneras y no puedo resolverlo.
LES PASO LO QUE HICE PARA QUE ME PUEDAN GUIAR EN DONDE ESTOY MAL.

Byte CanPalabras(AnsiString x)
{Byte c;
  if (x == "") {//Caso Base
c = 0;
}else{//Caso General

AnsiString letra = x[x.Length()];
x.Delete(x.Length(),1);
c = CanPalabras(x);

if (letra == " ") {
c++;
}
}
return c;

}


LES AGRADEZCO DE ANTEMANO

Xyzed

Hola.

Ya habías abierto un post con la misma pregunta. Tendrías que haber comentado en el mismo posteo la consulta, no está permitido abrir dos temas distintos sobre lo mismo.

Saludos.
...

Eternal Idol

AnsiString no es standard, usa std::string y depura tu codigo.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

ronbay

ya lo resolvi..NO BUSCABA QUE LO HAGAN SOLO QUE ME DEN SU PUNTO DE VISTA, POR AHI ESTOY IGNORANDO ALGO
Byte CanPalabras(AnsiString x)
{Byte contador;

  if (x.Length()< 2) {//Caso Base
contador= x.Length();
}else{//Caso General

char letra = x[x.Length()];
x.Delete(x.Length(),1);
char penul = x[x.Length()];
contador = CanPalabras(x);
if (letra != ' ' && penul == ' ') {
contador++;
}
}
return contador;


MUCHAS GRACIAS DE TODOS MODOS.

Serapis

#4
La cualidad que distingue una palabra de otra, es que medie un separador entre las palabras, cuando son más de una.

A su vez esto exige definir palabra y separador:
letra = 0|1|2|3...8|9|A|B|C...Y|Z|a|b|c|d...y|z| ...etc, si se precisan más
separador: espacio|tabulador|,|.|:|;|"| ...etc... si se precisan más
separadores = separador+   //uno o más separadores
palabra = letra+ // una o más letras
palabras = palabra [separador palabra]*

Una vez claro que letras pueden (son admitidas para) formar palabras y qué caracteres son un separador, se crean un array de 256 bytes indicando para cada uno, si es letra, separador (o no se admite = 0). Ese valor se toma de una enumeración y el array se crea al iniciar la aplicación.



array bytes Letras(256)

enumeracion ValorPalabra
   CARACTER_NO_APROBADO =0
   CARACTER_ES_LETRA = 1
   CARACTER_ES_SEPARADOR = 2
fin enumeracion

funcion inicializar
    ...
    Letras(09) =  CARACTER_ES_SEPARADOR  // el tabulador horizontal
    Letras(32) =  CARACTER_ES_SEPARADOR  // el espacio
    ...
    Letras(34) =  CARACTER_ES_LETRA   // comillas dobles
    ...
    Letras(48) =  CARACTER_ES_LETRA   // el dígito 0...
    ...
    Letras(65) =  CARACTER_ES_LETRA   // la letra A...
    ...
    Letras(97) =  CARACTER_ES_LETRA   // la letra a...
    ...
Fin funcion

La función se puede simplificar si se mete cada caracter aceptado como letra en un string y cada caracter admitido como separador en otro, y luego en sendos bucles, simplemente se toma cada carácter de dicho string y se le asigna el valor que toca.
El resto de caracteres tendrá el valor 0, señalando que o bien es un error o bien que se ignorará... (al gusto).

Finalmente puedes crear tu función, que sí, que puede ser recursiva, aunque es el tipo de casos que claramente no lo requiere, pero que para prácticas es adecuado.
En cuyo caso, convendría


entero BuscarPalabra(string Texto, entero Inicio, entero NumChars)
   entero j = inicio

   si (inicio = numchars) devolver 0 // impide buscar más allá del tamaño del texto.

   Hacer mientras  (texto(inicio) <> CARACTER_ES_SEPARADOR)  //caracteres no aprobados entre letras los ignora como si fueran letras.
       inicio +=1
       si (inicio = numchars) devolver 1
   repetir
   
   Hacer mientras  (texto(inicio) <> CARACTER_ES_LETRA)  // caracteres no aprobados entre separadores los ignora como separadores.
       inicio +=1
       si (inicio = numchars) devolver 1
   repetir
   
   si (inicio > j)   // caracteres no aprobados, pueden falsear esto.
       devolver  BuscarPalabra(texto, inicio, numChars) +1
   sino
       devolver  BuscarPalabra(texto, inicio, numChars)
   fin si
fin funcion


La función se invocaría tal que así:

texto = "Hola, esto es "..." 0001 ejemplo de pru3ba."
numPalabras = BuscarPalabra(texto, 0, texto.length)
mostrarMensaje "El texto: " + saltodelinea + texto + saltodelinea + "contiene: " + numpalabras + " palabras."

Cada llamada a la funcion BuscarPalabra, reconoce una palabra (o ninguna cuando se alcance el final).

Es del todo importante decidir qué caracteres pertencen a cada uno de los 3 grupos. Idealmente el grupo 'CARACTER_NO_APROBADO' no debería existir. Pero como nada es perfecto, ahi están. Se pueden ignorar o marcar como error, en el pseudocódigo se ignoran, pero su aparición puede arrojar error bajo determinadas condiciones, no se contempla evitar dicho errror, so pena de un código más complejo que luego interferirá con la comprensión.

Por supuesto, no necesitas construir el array ni tirar de la enumeración, sino del propio lenguaje, pero igualmente es preciso ilustrar dichos conceptos, sea que luego se construya o no. Para comprender el asunto, es preferible recrearlo y ver lo sencillo que es resolverlo.

El pseudocodigo está escrito al vuelo, pudiera hacerle falta un repaso, que queda a tu esfuerzo... lo mismo que entenderlo, y convertirlo a código.

...y no, no es necesario eliminar letras... imagina un texto de 100 millones de palabras, si con cada letra tienes que reconstruir otra cadena donde sea idéntica excepto en que ahora no tiene el que antes era el carácter primero/o ultimo (lo mismo me da, que me da lo mismo)... se haría eterno... simplemente avanza el puntero de lectura del char sobre el texto.

dijsktra

Aqui te va una propuesta de conteo de palabras con recursion...

(No es pa tanta frustración... Más se perdio en Cuba, que decía mi abuelo... ::) :D     )

Decir que es imprescindible llevar control de la primera posición de la linea - si queremos admitir lineas vacias - y del resultado provisional.





#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>


// Immersion:
// ac = #i : 0 <= i < n : V[i]='nb' and (i>0 -> V[i-1]='b')
// (s act as index n, in C-ish style)
// 0 <= n <= len(p)
int num_wordG(const char *p,const char *s, int ac)
{
 if (*s)
   if (isspace(*s)) return num_wordG(p,++s,ac); // Rec.
   else return num_wordG(p,s+1,ac+(p==s || isspace(*(s-1)))); // Rec.
 return ac; // Basis case.
}


int main(int argc, char *args[])
{
 char *line = NULL;
 size_t len = 0 ;
 ssize_t nread;
 for ( ; (nread = getline(&line, &len, stdin)) != -1; )
   {
     line[nread-1]=0; // chop the \n
     printf("%s -> %i\n",line,num_wordG(line,line,0));
   }
 free(line);
 return 0;
}





Algunos casos de prueba...


En un lugar de la Mancha
En un lugar de la Mancha -> 6
son 3 palabras
son 3 palabras -> 3
una
una -> 1

-> 0

Si la depuración es el proceso de eliminar fallos en el software, entonces programar debe ser el proceso de ponerlos dentro. (Edsger Dijsktra)

ronbay

Gracias bro..con eso lo voy a mejorar el programa.