Pascal/Turbo Pascal - Procedimiento y funciones

 
Vista:
sin imagen de perfil
Val: 2
Ha aumentado su posición en 11 puestos en Pascal/Turbo Pascal (en relación al último mes)
Gráfica de Pascal/Turbo Pascal

Procedimiento y funciones

Publicado por Dario (2 intervenciones) el 30/05/2020 04:31:59
pascal

Hola como estan?buenas noches, disculpen me podrian ayudar con este ejercicio de pascal, funciones,procedimientos y secuencias, no la tengo muy clara, estoy desesperado, espero que puedan ayudarme, desde ya se los agradecere!!saludos
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: 112
Bronce
Ha mantenido su posición en Pascal/Turbo Pascal (en relación al último mes)
Gráfica de Pascal/Turbo Pascal

Procedimiento y funciones

Publicado por juanba (40 intervenciones) el 30/05/2020 19:44:36
Buenos días. Espero que hayas dormido bien ;-)
Me encanta tu pregunta. La verdad es que si no la tienes clara, vas a tener problemas porque es el PPPP (Paradigma del Perfecto Programador en Pascal).
No te voy a resolver el ejercicio pero sí puedo aportar algunas ideas:
- No se dice si hay algún límite en el número de secuencias ni en su longitud.
Para poder definir una estructura de datos que contenga las secuencias sería bueno saber si existen estos límites.
- ¿Puede haber varias secuencias de la misma longitud o todas tienen que ser de longitud diferente? Conviene saberlo porque si puede haberlas se plantea la siguiente cuestión:
- El planteamiento dice que hay que ordenar las secuencias según su longitud. ¿Qué pasa si hay varias secuencias de la misma longitud?
¿Se deben dejar en la pila Resultado en el mismo orden en que estaban en la pila Origen? Es decir, si la secuencia '567' aparece en Origen antes de '358', también aparece antes en la pila Resultado.
¿O bien ordenarlas según la numeración que contienen? Ej '358' va antes de '567' porque 358 < 567 sin tener en cuenta la posición en la secuencia Origen.
¿O es indiferente y pueden ir en cualquier orden en la pila Resultado? (dentro del grupo de las secuencias de su misma longitud).

Con estos dos temas ya tienes información en cuanto a lo de asumir condiciones especiales que no están en el enunciado.
Había pensado proponerte una solución de fuerza bruta, o sea fácil de explicar pero poco eficiente. Pero he cambiado de opinion y voy a por otra solución un poco más "sofisticada". Si es demasiado farragosa, la podemos dejar por si es útil para otra persona.
Lo que te propongo es hacer un barrido de la secuencia de Origen, extraer el indice de inicio y la longitud y después ordenar las secuencias por longitud.
Una vez que estén ordenadas, construir la pila Resultado recuperando los datos de la secuencia en la pila origen en el orden de menor a mayor longitud.

Como en el planteamiento hay referencias a la manera de nombrar funciones y procedimientos, voy a seguir la regla
de nombrar los procedimientos con un verbo indicando la acción que realizan. Y también voy a aplicar un límite al tamaño de la pila de Origen y al número de secuencias.
Si esto no fuera válido, se podría solventar utilizando un array dinámico para contener la pila origen, pero no sé si esto está en vuestro plan de estudios.
Vamos a ir a lo sencillo y utilizar un array normal para contener las secuencias.
Y voy a limitar el tamaño de la pila a 100 elementos.

1
2
3
4
5
6
7
8
9
10
11
12
const TamPila = 100;
      MaxSecuencia = TamPila div 2;       {Al estar las secuencias separadas por ceros,}
                                    	  {una secuencia ocupa al menos 2 lugares}
type TPila = array[1..TamPila] of Integer;
     TIndice = Word;
     TPuntSecuencia = Record              {Identificación de cada secuencia en la pila Origen}
	   PuntInicio: TIndice;
	   Longitud: Word;
	 end;
	 TListaSec = array[1..MaxSecuencia] of TPuntSecuencia;     {Lista de los identificadores de todas las secuencias}
var Origen = TPila;
    NumSecuencias: Word;

No está definido cómo va a ser la entrada de datos, o sea la definición de la pila Origen. Es importante asegurarse de que los elementos del array que no estén utilizados por las secuencias, deben ponerse a cero. O se que Origen puede ser algo parecido a:
3 9 1 4 0 3 0 4 6 0 5 7 0 8 0 6 5 4 8 0 2 5 0 0 0 0 0 0 0 ...<muchos ceros> 0 0 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
27
28
29
30
31
32
33
34
35
36
//-----------------------------------------------------------------------------
// ExtraerSecuencias
// Rutina que hace un barrido de la pila para definir el puntero al inicio
// de cada secuencia y su longitud y pone estos datos en ListaSec.
// No es necesario pasar Pila como parámetro var, pero puede que sea
// conveniente, especialmente si el tamaño de la pila es grande
// (para evitar que el programa emplee recursos haciendo una copia).
// El barrido se detiene cuando se detecta el final del array o hay dos
// ceros seguidos (todos los demás elementos hasta el final también son cero).
// Si el programa conoce el número de secuencias desde el principio, no
// es necesario calcularlo aquí, pero no se define como es la
// introducción de secuencias en el programa.
//-----------------------------------------------------------------------------
procedure ExtraerSecuencias(var Pila: TPila;var ListaSec: TListaSec; var NumSec: Word);
var n, punt: TIndice;
begin
  NumSec := 0;
  n := 1;
  punt := 1;
  Repeat
                              {Ha terminado la secuencia que se estaba tratando?}
    if (Pila[n] = 0) or (n = TamPila) then
    begin
      Inc(NumSec);
      ListaSec[NumSec].PuntInicio := punt;
      ListaSec[NumSec].Longitud := n - punt;
                        {Si n apunta al siguiente cero, la longitud es n - punt pero si ha llegado al final de la pila, n apunta al}
			{ultimo numero de la secuencia y la longitud es 1 más}
      if (n = TamPila) and (Pila[n] <> 0) then
	Inc(ListaSec[NumSec].Longitud);
      if n < TamPila then
        punt := Succ(n);     {o punt := n+1. apuntar al inicio de la siguiente secuencia}
    end;
    Inc(n);                  {o n := n+1. apuntar al inicio de la siguiente secuencia}
  until (n >= TamPila) or ((Pila[n] = 0) and (Pila[n-1] = 0));
end;

En relación con las indicaciones del ejercicio, hay que decir que esta rutina realiza tanto gestión (obtención de la lista de secuencias ListaSec) como cálculo (obtención del número de secuencias NumSec). Se podría dividir en dos rutinas diferentes, pero lo cierto es que aquí surge de un modo tan natural (únicamente requiere la instruccion Inc(NumSec) en la detección de cada secuencia) que soy partidario de dejarla así.
Una vez que se ha obtenido la lista de secuencias, hay que ordenarla. Empleo un algoritmo de ordenación copiado de N.Wirth (Algorithms + Data Structures = Programs) capítulo 2.2.1 Sorting by Straight Exchange, también llamado Bubble Sort pero se puede emplear cualquier otro.
Lo que no me he puesto a averiguar es como deja el programa de ordenación los grupos de secuencias con la misma clave (o sea, con la misma longitud). Este criterio no está definido en el planteamiento del ejercicio. Creo que Bubble Sort respeta el orden inicial. Ya lo he comentado al principio.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure OrdenarPorBubbleSort(var ListaSec: TListaSec; NumSec: Word);
var i, j: TIndice;
    x: TPuntSecuencia;
begin
  for i := 2 to NumSec do
  begin
    for j := NumSec downto i do
      if ListaSec[j-1].Longitud > ListaSec[j].Longitud then
      begin
	x := ListaSec[j-1];
	ListaSec[j-1] := ListaSec[j];
	ListaSec[j] := x;
      end;
  end;
end;

Despues de ejecutar este procedimiento tenemos la ListaSec con las secuencias ordenadas de menor a mayor longitud. Ahora a construir la pila Resultado.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
procedure ConstruirResult(var Origen, Resultado: TPila; var ListaSec: TListaSec; NumSec: Word);
var n, k: Word;
    iOrig, iResult: TIndice;
begin
  iResult := 0;
  for n := 1 to NumSec do
  begin
    iOrig := ListaSec[n].PuntInicio;
    for k := 1 to ListaSec[n].Longitud do
    begin
      Inc(iResult);               {Avanzar el indice para colocar este valor}
      Resultado[iResult] := Origen[iOrig];
      Inc(iOrig);                 {a por el siguiente numero de la secuencia origen}
    end;
	                          {Si no se ha llegado al final, añadir el separador}
    if n < NumSec then
    begin
      Inc(iResult);
      Resultado[iResult] := 0;
    end;
  end;
end;

Sospecho que ahora estarás el doble de desesperado. Pero si puedo ayudarte con alguna aclaración, aquí estamos.
Ah, he hecho la prueba y (después de algunas correcciones) funciona.

Suerte y no hay que desesperarse.


La_Web_del_programador_01
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