[ Foro de Pascal ]
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.
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.
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.
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.
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.
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.
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.
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.)