Pascal/Turbo Pascal - Necesito ayuda con un programa de string

 
Vista:

Necesito ayuda con un programa de string

Publicado por Maria (1 intervención) el 16/06/2020 06:22:10
Holaaa, quisiera algo de ayuda con este programa, no se como hacerlo, {Dados dos números enteros P y S, contar la cantidad de casos en que una palabra de P caracteres esta seguida por una palabra de S caracteres, a partir de una frase dada por el usuario. Por ejemplo si el usuario da la frase 'La mesa hay que pintarla con un color de moda' y P=2 y S=4, entonces daría como resultado dos casos, los cuales son 'la mesa' y 'de moda'}
Solo puedo utilizar estructuras repetitivas y string, por favor ayuda!!!
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 95
Oro
Ha mantenido su posición en Pascal/Turbo Pascal (en relación al último mes)
Gráfica de Pascal/Turbo Pascal

Necesito ayuda con un programa de string

Publicado por juanba (32 intervenciones) el 16/06/2020 16:51:09
Se trata de encontrar en un string grupos de dos palabras de las cuales la primera tiene una longitud P y la segunda una longitud S.
¿Como podemos identificar una palabra y conocer su longitud? Averiguando en que posiciones del string comienza y termina la palabra.
¿Donde puede comenzar una palabra? En el primer caracter "no espacio" del string o el primer caracter "no espacio" despues de un espacio.
¿Donde termina una palabra? En el ultimo caracter "no espacio" antes de un espacio.o en el final del string

Y por supuesto el final de cada palabra debe ser posterior al inicio, y el comienzo de cada palabra debe ser posterior al final de la anterior.
Asumo que el unico separador entre palabras es el espacio ' ' o caracter 32 en el código ASCII. En teoría puede haber otros como el
retorno de carro y el salto de línea, pero vamos a mantener el ejemplo sencillo.

Vamos a hacer un procedimiento que obtenga las direcciones de inicio y final de la primerra palabra que aparezca desde una direccion dada. Construimos una funcion que admite como parámetros la frase a tratar y la direccion a partir de la cual queremos encontrar una
palabra. Por ejemplo, si Frase = 'La mesa hay que pintarla con un color de moda' i DirIni = 8, la palabra que encontrará será 'hay' que está en la posicion 9 y tiene una longitud de 3 caracteres. La funcion que presento a continuacion devolvería un 9 en DirIni y un valor de 3 como resultado de la funcion. Si no se encuentra ninguna palabra, devuelve 0.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const Espacio = ' '; {Hay un espacio vacio entre las dos comillas }
 
Function CalcPalabra(Frase: string; var DirIni: Integer): Integer;
var DirFin: Integer;
begin
  CalcPalabra := 0;   {Con esto indicamos que no hemos encontrado ninguna palabra}
  if (DirIni > 0) and (DirIni <= Length(Frase)) then {Comprobar que el punto de partida esta dentro de la frase}
  begin
                      {Si estamos sobre un espacio, avanzar hasta el primer caracter no-espacio }
    while (DirIni <= Length(Frase)) and (Frase[DirIni] = Espacio) do
      DirIni := DirIni + 1;
                      {Si hemos llegado al final de la frase no hay más que hacer}
                      {Pero si todavia no estamos alli...}
    if DirIni <= Length(Frase) then
    begin
      DirFin := DirIni; {Apuntar al primer caracter no-espacio}
                      {Y ahora buscar el final avanzando los no-espacios}
      while (DirFin <= Length(Frase)) and (Frase[DirFin] <> Espacio) do
        DirFin := DirFin + 1;
	             {El bucle anterior puede terminar por fin de la frase o por }
         	     {encontrar un espacio. En ambos casos "DirFin" se ha pasado}
                     {del final de la palabra. Y la longitud es: }
      CalcPalabra := DirFin - DirIni;
    end;
  end;
end;

Para comprobar que funciona ejecutamos el siguiente código:

1
2
3
4
5
6
7
8
9
10
11
begin
  D := 1;
  Frase := 'La mesa hay que pintarla con un color de moda';
  repeat
    L := CalcPalabra(Frase, D);
   if L > 0 then
      writeln('D = ', D:3, '    L=', L:2, '      Palabra = ', Copy(Frase, D, L));
    D := D + L + 1;
  until L = 0;
  readln;
end.

Y obtenemos:

Ejercicio_string_01

Con esta funcion ya es facil resolver el ejercicio: Se van aislando las palabras una por una y cuando aparezca una de longoitud p se comprueba si la siguiente tiene longitud S. O se pueden copiar todas las logitudes en un vector y luego examinarlo para ver si en su secuencia de valores aparece la pareja P, S. En fin no es nada complicado.
Un ejemplo que tiene algunas oportunidades para optimizar, pero funciona creo que funciona::

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Procedure ComprobarParejas(Frase: string; LongP: Integer; LongS: Integer);
var DirIni1,       {Direccion inicial de la primera palabra}
    DirIni2, 	   {Direccion inicial de la segunda palabra}
    Long1: Integer;{Longitud de la primera palabra}
begin
  writeln('Ancho de la Primera = ', LongP, '   y la segunda = ', LongS);
  DirIni1 := 1;
  repeat
    Long1 := CalcPalabra(Frase, DirIni1);
    if Long1 = LongP then
    begin          {La palabra que empieza en Dirini cumple la condicion P}
      DirIni2 := DirIni1 + LongP + 1;
                   {Buscamos la palabra que empieza a continuacion}
      if (DirIni2 <= Length(Frase)) and (CalcPalabra(Frase, DirIni2) = LongS) then
      begin        {Y oh Maravilla! La siguiente palabra cumple la condicion S}
    	Writeln('Encontrada la Pareja "', Copy(Frase, DirIni1, LongP), ' ', Copy(Frase, DirIni2, LongS), '"');
      end
    end;
    if Long1 > 0 then
      DirIni1 := DirIni1 + Long1 + 1;   {Apuntar a la siguiente palabra}
  until Long1 = 0;
end;

Quedan por solucionar los detalles de pedir al operador los valores de P y S, así como la frase e integrar estos procedimientos en un programa completo. Eso, a gusto del consumidor.
Es mejor restringir los caracteres de la frase a los disponibles en el codigo ASCII porque las eñes, vocales acentuadas i vocales con diéresis ocupan más de un byte por caracter y eso podría hacer descarrilar la función CalcPalabra.

Suerte y que tengas un buen día.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 95
Oro
Ha mantenido su posición en Pascal/Turbo Pascal (en relación al último mes)
Gráfica de Pascal/Turbo Pascal

Necesito ayuda con un programa de string

Publicado por juanba (32 intervenciones) el 18/06/2020 16:28:01
Revisando las rutinas que puse, veo que solo valen para el caso de una única frase sin signos de puntuación. Si el texto contiene varias frases, o una frase larga con comas, comillas y otros signos que puedan actuar de separadores además del espacio, hay que tenerlos en cuenta tambien.

Voy a dar una pista de como lo haría:

1
2
3
4
5
6
const ConjuntoSeparadores = [' ', '.', ',', '"', ';', ':', '(', ')', '$', '@', '/', '-'];   {Poner aqui todos los separadores que se usen}
                       {y sustituir cada comprobación del tipo "caracter = Espacio"}
                       { o "caracter <> Espacio" por "caracter in ConjuntoSeparadores" o }
                       { "not (caracter in ConjuntoSeparadores)" respectivamente}
                        { Por ejemplo, la comprobacion:}
 (Frase[DirIni] = Espacio)    {se convertiria en: } (Frase[DirIni] in ConjuntoSeparadores)

Buena suerte.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar