[ Foro de Pascal ]

Comparando Arrays en pascal

03-Nov-2015 20:50
Invitado (Martin)
7 Respuestas

Buenas.
Haciendo unos ejercicios me surgió la siguiente duda:  ¿cómo puedo hacer para comparar dos arrays con las siguientes condiciones?

Suponiendo que los arreglos son los siguientes:

     Arreglo1                     Arreglo2
|1|2|1|2|7|8|   y   |1|2|3|4|5|6|

Quiero contar la cantidad de elementos que tiene en la misa posición que el otro, por ejemplo 1 en este caso. Se encuentra en la primera posición en ambos arreglos. Bien, eso lo tengo con el siguiente for:

for i:=1 to MaxArray do
    if arreglo1[i]= arreglo2[i] then
          seEncuentra:=seEncuentra+1;

Ahora, también quiero contar la cantidad máxima posible de veces que pasaría esto si permutara de lugar en el segundo array, pero sin repetir.

Aquí encontramos que el Arreglo2 contiene un |1| en la misma posición que el Arreglo1. Si yo lo pusiera en la posición 3 tendría dos chances, pero justamente no quiero que cuente las cuente a ambas. No encuentro un algoritmo para hacerlo, no puedo hacer que solamente de una vuelta, pruebo con 2 for anidados pero se pasa.

En el caso de que pase lo siguiente

|1|2|1|2|7|8|        |2|2|2|2|2|2|     lo que hice fue esto |1|2|1|2|7|8|        |2| .

Creo que no quedo muy bien explicado, espero que lo puedan entender y ayudarme. Muchas gracias.


03-Nov-2015 22:36
Invitado (Martin)

En lugar de pensar eso, me ayudaría mucho si me pasaran un código me mueva todo el vector hacia atrás de la siguiente forma:

|1| |2|  |  |1| ------->   |1|2|1| | | |

No puedo lograrlo, pero si consigo eso ya puedo lograr lo otro.


13-Nov-2015 20:31
Nacho Cabanes (+83)

La forma que planteas de comparar si están en las mismas posiciones es correcta.

Lo que no entiendo es lo de "permutar el segundo array sin repetir". Tampoco tengo clara la segunda pregunta, que muestra "huecos" en el array. Un array no puede tener huecos, sino, en todos caso, posiciones marcadas como no utilizadas, pero para eso sería necesario usar un segundo array o tener "records" en vez de números en cada posición.


16-Nov-2015 20:15
Invitado (Martin)

Gracias por responder. No me explique muy bien, lo leo y es un dificil de entender.
Lo que quiero que haga es comparar los 2 arrays y ver como puede contar las veces que un numero del array uno pero en el array 2. Lo dificil es hacerlo sin repetir.
Con repetir me refiero a lo siguiente:

Si tengo |1|2|1|2|7|8| y el otro es |2|2|2|2|2|2| quiero que cuente la cantidad de veces que se encuentra el 2 del segundo en el primero. Pero al tener todo el array lleno de 2 quiero que solo cuente uno. Es algo asi como el logaritmo del mastermind para calcular buenos y regulares.


16-Nov-2015 20:42
Nacho Cabanes (+83)

La idea básica para ver los elementos comunes sería:


para cada elemento x de A2
    para cada elemento y de A1
        si x = y entonces aumentar contador


Si además no quieres que te cuente varias veces los repetidos, necesitarías otro "for", para comparar ese dato con todos los elementos anteriores de A2


para cada elemento x de A2
    para cada elemento y de A1
        si x = y entonces 
            repetido = falso
            para cada elemento z de A2 anterior a x
                si x = z entonces repetido = verdad
            si repetido = falso entonces aumentar contador


Hay otras alternativas, pero esa debería resultar bastante sencilla.


16-Nov-2015 22:25
Invitado (Martin)

Gracias nuevamente por responder. Lo hice parecido pero sin el booleano. Lo que hice fue decirle que si encontraba un elemento repetido siendo j e i diferentes, que anule los dos elementos en los array. Por anular me refiero a colocar un numero fuera del rango, que me dan.

Muchas gracias.


18-Nov-2015 18:20
Luis Torres (+18)

Este tipo de problemas en los que hay que realizar operaciones con un elemento que se repite dentro de un grupo, suelo enfocarlos con Conjuntos. Creo que es mucho más sencillo de entender así que enfocarlo meramente con el uso de arreglos. Hace tiempo hice un programa parecido, así que modifiqué un tanto y te lo dejo a continuación. Entender Conjuntos y su aplicación en Pascal es bastante sencillo y útil, te ahorrará muchos dolores de cabeza. Espero que estudies el código y te sirva de mucho:


program ContarElementosComunesEnDosArreglos;

const
  MAX1 = 6;
  MAX2 = 6;
  Arreglo1: array[1..MAX2] of integer = (1,2,1,2,7,8);
  Arreglo2: array[1..MAX1] of integer = (2,2,2,2,2,2);
 
type
  TipoConjuntoNaturales = set of byte;  { Definimos un tipo de Conjunto de numeros enteros }
  
var
 Enteros: TipoConjuntoNaturales; { Declaramos la varialbe tipo conjunto }
 i, j, contador: integer;


BEGIN
 Enteros:= [];  { Inicializamos la variable de conjunto a vacio. Enteros es, entonces, un conjunto sin elementos }
 
 { Ahora vamos a trabajar con el Arreglo2. Introduciremos en la variable de conjunto (Enteros) los elementos }
 { del Arreglo2, al final en Enteros tendremos almacenados los elementos no repetidos de dicho arreglo.      }
 for i:=1 to MAX2 do
  Begin
    if (not (Arreglo2[i] in Enteros) ) then  { Si el elemento de Arreglo2 no esta en el conjunto Enteros, los introduce }
	 include(Enteros,Arreglo2[i]);           { esto nos asegura que si el elemento esta repetido, no haga nada          }
  End;
  
  { En esta parte vamos a recorrer, con cada elemento del Arreglo2, el Arreglo 1 y los repetidos se contaran en la      }
  { variable "contador". Para que se realice este conteo, el elemento del Arreglo2 debe aparecer en la variable de      }
  { de conjunto "Enteros", es importante excluir el elemento del conjunto al finalizar el conjunto de instrucciones     }
  { del ciclo, para asi evitar que se vuelva a considerar el mismo elemento.                                            }
  for i:=1 to MAX2 do
   Begin
    if (Arreglo2[i] in Enteros) then
	 Begin
	  contador:= 0;
      for j:=1 to MAX1 do
	   if (Arreglo2[i] = Arreglo1[j]) then
	    contador:= contador + 1;
	  writeln('El elemento ', Arreglo2[i], ' del segundo arreglo se repite ',contador,' veces en el primer arreglo.');
      exclude(Enteros,Arreglo2[i]);	  
	 End;
   End;	

 readln;
END.  


Saludos.


19-Nov-2015 23:47
Invitado (Martin)

Muchas gracias a ambos. Ahora 3 ejercicios  despues pide hacer una funcion booleana que retorne true si se cumplen estas condiciones.

1)Halla los buenos y regulares entre C y H(i).        (H(i) es un codigo de la historia, para cada "i" hay un codigo distinto porque es un arreglo.

2)Fijate si el resultado que obtuviste es igual al que tenias guardado en la historia para H(i).

3) Si para todo H(i) de la historia, se cumple que coincide ese resultado, entonces EsApropiado es TRUE.

Si existe al menos un H(i) que te de buenos o regulares distintos, entonces EsApropiado es FALSE.


Con H se refiere a una historia del siguiente tipo:  TipoCodigo = array [RangoCodigo] of char;
   TRegistroNota = record
      codigo : TipoCodigo;
      buenos,
      regulares: RangoBR;
   end;

   THistoria  = record
   info : array [1..MAXIMO_INTENTOS] of TRegistroNota;
   tope : 0..MAXIMO_INTENTOS;
   end;

Estoy casi por obtenerlo, pero un codigo en especial hace que este mal la funcion.






(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.)