[ Foro de Pascal ]

cadena: extraer una palabra

18-Jan-2016 20:16
Invitado (ramiroponce)
11 Respuestas

hola buenas, espero este foro me ayude es que estoy teniendo problemas para aprender a programar

dada una frase que termina en un punto, y un numero n determinar la n-esima palabra de la frase, si no hay tantas palabras el resultado sera una cadena vacia.

mi gran duda es como voy contando palabra y extraer la palabra que coincida con el numero n, dado? cualquier ayuda me hara caer en cosas que quiza no las veo, gracias


20-Jan-2016 22:54
Luis Torres (+18)

Se recorre la frase u oración desde el primer carácter hasta el último, si encuentra un espacio en blanco o un punto se incrementa el contador de palabras en 1 ( el contador se inicializa en cero ). Se asume que la frase no comienza ni finaliza con espacios en blanco, que cada palabra está separada de la que le sigue por solo un espacio en blanco y, la frase no contiene ningún signo de puntuación, únicamente el punto final. Cuando el contador coincida con el número dado n, debemos hacer un recorrido hacia atrás hasta encontrarnos con un espacio en blanco o con el inicio de la frase, si llegamos al final y el contador sigue siendo menor al número dado n, entonces la función deberá devolver la cadena vacía. Así, mas o menos se resuelve el problema.

Saludos.


21-Jan-2016 05:27
Invitado (ramiroponce)

gracias compañero luis, sin embargo no se como hacer la parte que me indicas de:
debemos hacer un recorrido hacia atrás hasta encontrarnos con un espacio en blanco o con el inicio de la frase, como podria ser eso luis? como se el inicio de la frase al retrocederme?


gracias por tu gentileza


22-Jan-2016 04:59
Luis Torres (+18)

Cuando encuentras un espacio en blanco o el punto final es porque acabas de recorrer una palabra completa, ese espacio o punto indican el final de la palabra; entonces, lo que quedó atrás hasta el anterior espacio en blanco o comienzo de la frase es la palabra. El recorrido hacia atrás lo puedes hacer con un ciclo for de la siguiente manera,  for i:= posicionActual downto 1 do. Solo te interesarán los caracteres que están hasta el espacio en blanco anterior o al comienzo de la frase, los demás deséchalos.  Eso es todo.

Saludos.


23-Jan-2016 05:19
Invitado (ramiroponce)

compañero luis gracias por responderme, yy disculpa que te haga una nueva pegunta, ese for decreciente debe estar dentro de un while o un repeat o como hago para saber con ese for que me indicas que he llegado a un espacio en blanco o al inicio de la frase, como serian esas condiciones compañero y gracias por tu ayuda.


24-Jan-2016 03:09
Luis Torres (+18)

Se puede hacer con un condicional, de la siguiente forma:


if (frase[i]<>' ') and (i>1) then     (*  Si el caracter actual es distinto de espacio en blanco y aun no  *)
                          .                                          (*  hemos llegado  al inicio de la frase u oracion  *)
                          .
                          .


Saludos.


24-Jan-2016 05:59
Invitado (ramiroponce)

que buena idea luis yo habia pensado en un while pero asi es mas claro para mi, lo que si queria por ultimo es preguntarte esta condicional que me indicas iria dentro del for o el for es el que va dentro del if, gracias por tu ayuda


25-Jan-2016 04:14
Invitado (Luis)

Es indistinto si usas un ciclo for o uno while, de hecho éste último es más eficiente porque puedes detener la ejecución  de la búsqueda cuando encuentres la palabra. Te recomendé un for, porque es más fácil de entender. Podrías usar un ciclo for para recorrer la frase completa y otro while interno para hacer el recorrido hacia atrás, y con el if detectar el espacio en blanco anterior. Es un poco complicado de explicar, pero cuando tomes bien la idea y trabajando directamente en el código lo entenderás perfectamente. Esta es mi idea, pero estoy seguro que el prof. Nacho Cabanes tiene una mucho mejor y más fácil de implementar. Vamos a esperar a ver si se pronuncia al respecto.

Saludos.


25-Jan-2016 23:51
Nacho Cabanes (+84)

Yo usaría un "for" para recorrer la cadena de principio a fin, e iría contando espacios. Cada espacio indica el principio de una nueva palabra (salvo la primera, que empieza en la letra 1).  Así, si encuentras el primer espacio, estás al final de la primera palabra y al comienzo de la segunda; si encuentras el primer espacio, estás al final de la primera palabra y al comienzo de la segunda... y así sucesivamente.

Finalmente, con "copy" puedes extraer la subcadena que empieza en una cierta posición y tiene una cierta longitud. Así, una versión "no robusta" (no contempla espacios iniciales, ni repetidos) podría ser:


program BuscarPalabra;

var 
    i: byte;
    palabraBuscada: byte;
    frase: string;
    palabrasEncontradas: byte;
    posInicio, posFin: byte;

begin
    palabraBuscada := 4;
    frase := 'hola, que tal estas este dia';
    palabrasEncontradas := 1; 
    posInicio := 1;
    posFin := length(frase);
    for i := 1 to length(frase) do
    begin
        if frase[i] = ' ' then
        begin
            palabrasEncontradas := palabrasEncontradas+1;
            if palabrasEncontradas = palabraBuscada then
                posInicio := i+1
            else if palabrasEncontradas = palabraBuscada+1 then
                posFin := i-1;
        end;
    end;
    writeLn( copy(frase, posInicio, posFin-posInicio+1) );
end.


 


26-Jan-2016 04:33
Luis Torres (+18)

Por mi parte, yo también hice un código que lo pongo a continuación:


program CadenaPalabras;

const
  frase: string = 'Esta es una frase para probar el codigo.';

var
  num, cont, i, j, posicionFinal, posicionInicial, numCaracteres: integer;
  interruptor: boolean;  


BEGIN
  writeln(frase);
  write('Indique el numero de la palabra que va a buscar: '); readln(num);
  writeln;
  cont:= 0;
  interruptor:= true;
  for i:=1 to length(frase) do
   Begin
     if (frase[i]= ' ') or (frase[i]= chr(46)) then
	  cont:= cont + 1;
     if (cont = num) and (interruptor) then
	  Begin
	    posicionFinal:= i;
        interruptor:= false;
		posicionFinal:= posicionFinal-1;
	    j:= posicionFinal;
        while (frase[j]<>' ') and (j>1) do
	      j:= j-1;
	    posicionInicial:= j;  
	    if frase[j]=' ' then
	      posicionInicial:= posicionInicial + 1;
        numCaracteres:= posicionFinal - posicionInicial + 1;
	    writeln(copy(frase,posicionInicial,numCaracteres));
      End;		
   End;
  if num>cont then
   writeln('La frase no contiene tantas palabras. Elija un numero inferior.');

  readln;
END.  


Saludos.


26-Jan-2016 05:53
Invitado (ramiroponce)

wuao excelente ayuda por parte del profesor y del compañero luis que veo colabora mucho en el foro, buena por esa luis, profesor en tu codigo tengo una duda permiteme pedirte un poco mas el por que lo haces, y es respecto a por que haces  posInicio := i+1 si porejemplo imaginate que n o para ti palabrabuscada:=1 , la n-esima palabra seria la palabra uno entonces por que al coincidir if palabrasEncontradas = palabraBuscada then pones posInicio := i+1, me podrias explicar mas a fondo esta parte profesor especialmente para este caso de la primera palabra coincidente con lan-esima palabra a buscar, muy amable profesor y luis


31-Jan-2016 17:59
Nacho Cabanes (+84)

No acabo de entender la pregunta, pero antes de mi fuente tienes descrito el planteamiento.






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)