Foros del Web » Programando para Internet » ASP Clásico »

encontrar duplicados en dos ARRAYs

Estas en el tema de encontrar duplicados en dos ARRAYs en el foro de ASP Clásico en Foros del Web. Buenas, gente. Estoy haciendo un sistema de "favoritos" en donde se guardan ID's de registros separados por comas en un campo memo (el contenido es ...
  #1 (permalink)  
Antiguo 31/07/2003, 13:12
Avatar de AlZuwaga
Colaborador
 
Fecha de Ingreso: febrero-2001
Ubicación: 34.517 S, 58.500 O
Mensajes: 14.550
Antigüedad: 23 años, 3 meses
Puntos: 535
encontrar duplicados en dos ARRAYs

Buenas, gente.

Estoy haciendo un sistema de "favoritos" en donde se guardan ID's de registros separados por comas en un campo memo (el contenido es similar a "BUE001, BUE002, CAT003, SFE156, ..., ETC000")

Los registros, los ID's separados por coma, son como máximo 2169 ya que corresponden a la totalidad de los municipios que hay en argentina y cada ID tiene un largo de 6 caracteres. Lo que da un máximo posible de 15182 caracteres (2169 * 6 + 2168 comas)

Ahora bien... El usuario puede manipular el contenido agregando más ID's o eliminando otros. Claro está que puede confundirse y agregar uno o más ID dos o más veces a este string separado por comas y el sistema se lo debería impedir. Un error grave que puede cometer es agregar a un nuevo grupo todos los registros (2169) y luego agregarlos nuevamente.

En un comienzo se me había ocurrido hacer un split (por la coma) del contenido actual y un split del contenido a agregar y comparar 1 a 1 si está duplicado. Suponiendo que el contenido actual sea de 2000 registros e intente agregar 1 más, serían 2000 comparaciones y realmente no me pareció mucho... pero viendo que puede pasar una situación como la arriba marcada en azul, serían 2.169 * 2.169 = 4.704.561 comparaciones (situación totalmente absurda en ese hipotético caso... pero me gusta ser extremista =)... y ahora SI me resulta como muuuucho

La pregunta, luego de planteado y ejemplificado el tema de la mejor manera que pude, sería la siguiente:

Cuál sería la forma más efectiva (o menos "consume recursos") de buscar una subcadena dentro de otra, verificar que la primera no exista en la segunda y finalmente anexarla?

Por ahora no pretendo nada más que teoría... el código lo haré en base a sus opiniones y si no me sale les pido ayuda

Saludos y gracias por leer todo este palabrerío insoportable

Última edición por AlZuwaga; 31/07/2003 a las 13:24
  #2 (permalink)  
Antiguo 31/07/2003, 13:35
 
Fecha de Ingreso: mayo-2002
Ubicación: La Rioja (España)
Mensajes: 18
Antigüedad: 22 años
Puntos: 0
Se que la respuesta es un poco absurda, pero no te sirve la funcion InStr?
  #3 (permalink)  
Antiguo 31/07/2003, 14:11
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 5 meses
Puntos: 98
mmmhhh, caso complejo...
veo que estas claves tienen todas 6 caracteres cierto?, las almacenas sin espacios? supongo que sería lo mejor.
Ahora, no veo viable hacer arreglos mediante split por la gran cantidad de memoria que ocuparías, pero, de las comparaciones en el caso extremo no veo que nadie te pueda salvar, lo que yo haría es crear una función que mediante mid, utilice el incremental de 6 para cortar cada uno de los fragmentos y hacer dichas comparaciones, incluso para optimizarla podrías hacer una recursiva en lugar de cíclica...aunque bueno, quizás la funución sea lo de menos

No veo que otra cosa sería mas adecuada para optimizar esto...

Salu2,
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #4 (permalink)  
Antiguo 31/07/2003, 14:45
Avatar de AlZuwaga
Colaborador
 
Fecha de Ingreso: febrero-2001
Ubicación: 34.517 S, 58.500 O
Mensajes: 14.550
Antigüedad: 23 años, 3 meses
Puntos: 535
Cita:
Mensaje Original por joanco
Se que la respuesta es un poco absurda, pero no te sirve la funcion InStr?
Joanco, la propuesta no es para nada absurda. Todo me sirve. Es más, ya lo había pensado más o menos así:

For i = 0 to ubound(subcadena)
If instr(cadena_original, subcadena(i)) = 0 then cadena_original = cadena_original & “,” & subcadena(i)
Next

Con lo que estaría usando sólo un arreglo y no 2 como pensé en la idea que tenía al escribir el primer mensaje.
Ahora mismo, escribiendo esto, se me ocurre que el script podría identificar cuál de los dos strings es el que contiene menos caracteres y convertirlo en un arreglo dejando el más largo para efectuarle las comparaciones. De esta manera el arreglo estaría ocupando menos en memoria al ser el más chico en elementos y las comparaciones serían las menores posibles.

Te digo más... voy a intentarlo de esa manera y probarlo en casos bastantes extremos a ver cómo reacciona y cuanto demora.
  #5 (permalink)  
Antiguo 31/07/2003, 14:54
Avatar de AlZuwaga
Colaborador
 
Fecha de Ingreso: febrero-2001
Ubicación: 34.517 S, 58.500 O
Mensajes: 14.550
Antigüedad: 23 años, 3 meses
Puntos: 535
Disculpas u_goldman, parece que tardé mucho en escribir este mensaje ;)

No había visto que respondiste... en realidad, cuando lo empesé a escribir todavía no estaaba tu respuesta, me puse a hacer cosas que pidieron y bueno.. me demoré un tanto :D


Cita:
las almacenas sin espacios? supongo que sería lo mejor
Actualmente las almaceno con los espacios (porque así me lo devuelve el request.form de los checkboxes), pero ya tenía pensado eliminarlos (fijate que ni los tuve en cuenta al hacer la suma de caracteres en el primer mensaje)

Ahora... te parece que manejar todo con funciones normales de cadenas sería más eficiente?

Y qué tal usando expresiones regulares? (que no las se usar, pero es buen momento para aprender)

salú
  #6 (permalink)  
Antiguo 31/07/2003, 15:13
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 5 meses
Puntos: 98
Yo creo que ambas opciones, serían mas eficientes que los arreglos, aunque también depende mucho de la máquina donde corras la aplicación, si tiene mucha capacidad de procesamiento y sobre todo los recursos libres suficientes, pos ni nos deberíamos preocupar.
Con respecto a las expresiones regulares ahí si quien sabe, me declaro totalmente neófito, alguna vez traté de hacer algo con ellas, pero como que van mas allá de mi comprensión
Y si, a mi me parece mucho mas eficiente manejarlo con funciones de cadenas, pa' mi que ocupas menor cantidad de memoria, y bueno, el problema de las iteraciones creo que sería el mismo para cualquier caso...

Salu2,
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #7 (permalink)  
Antiguo 31/07/2003, 15:46
Avatar de AlZuwaga
Colaborador
 
Fecha de Ingreso: febrero-2001
Ubicación: 34.517 S, 58.500 O
Mensajes: 14.550
Antigüedad: 23 años, 3 meses
Puntos: 535
Bueno.. igual espero más opciones hasta mañana.. ya es tarde y en un rato me voy a mi casa. así que ni pienso comenzar esto ahora :D

Si no hay nadie que entremedio aparezca y diga "STOP! Hacelo así y asá que está científicamente comprobado que es lo mejor" (:D), voy a probar lo del INSTR junto al arreglo menor posible y lo del MID, comparar resultados y quedarme con uno de ellos.


gracias
__________________
...___...
  #8 (permalink)  
Antiguo 01/08/2003, 01:00
 
Fecha de Ingreso: mayo-2002
Ubicación: La Rioja (España)
Mensajes: 18
Antigüedad: 22 años
Puntos: 0
Hola dazuaga, me alegro de que te sirviese la respuesta!

Otra cosa: ademas de usar InStr para comparar la cadena mas pequeña con la mas grande, puedes ordenar los elementos de las dos de menor a mayor, asi tienes el indice a partir del cual tienes que empezar a comparar y no necesitas comparar cada elemento desde el principio...
Problema: no se si hay alguna funcion que te ordene una cadena automaticamente, porque si no tendrias que hacerlo con un bucle y no solucionarias el problema del numero de comparaciones.
  #9 (permalink)  
Antiguo 01/08/2003, 02:01
Avatar de AlexNV  
Fecha de Ingreso: junio-2003
Ubicación: Madrid
Mensajes: 289
Antigüedad: 21 años
Puntos: 1
Hola,
Lo ideal sería que tuvieras ambas listas ya ordenadas, cosa poco probable.
Si fuera así y no tuvieras que ordenarlas tu, sería recorrer ambas listas del primer al último elemento, comparando en cada elemento (en el peor caso 2169 comparaciones)

No obstante, personalmente pienso que es un error de diseño, y lo que yo haría sería normalizar ese tabla, es decir, crear una tabla FAVORITOS con un campo ID y una clave foranea a la clave de la otra tabla. Puede que inicialmente te suponga más tiempo pero luego lo agradecerás, porque los problemas que no se arreglan al principio crecen y crecen exponencialmente durante el tiempo, y éste de la búsqueda puede ser sólo el principio...

Un saludo.
  #10 (permalink)  
Antiguo 01/08/2003, 02:58
 
Fecha de Ingreso: abril-2003
Ubicación: Madrid
Mensajes: 707
Antigüedad: 21 años, 2 meses
Puntos: 0
Hola, buenas ... dejando a parte problemas de diseño o no, que cada uno es muy libre de tener su información como mejor le venga para lo que va a necesitar, se puede tomar parte de lo que AlexNV dice.

Hay que tener en cuenta que el manejo de cadenas es lo más lento que tiene vb, entonces la opción de usar los intsr, y los mid, puedo resultar pesada de ejecutar.

Sin embargo, si creas una tabla temporal con un primary key por el campo que tu quieres comparar, haces un split, y los agregas a esa tabla, y posteriormente, vuelves a cargar los del segundo campo, controla los errores, y esos serán los repetidos.

No sé si será mas efectivo los split y los arrays o los instr y los mid

De todas formas... hay una cosa que no comprendo del todo de tu mensaje inicial.

Vas a tener un campo memo por usuario, en el que modifican los favoritos, y quieres compararlo contra otro campo ¿¿¿???
Pero que otro campo, en otra tabla, otro registro, proveniente de un textbox ¿¿¿??? de eso no me he enterado muy bien, no lo entiendo
  #11 (permalink)  
Antiguo 01/08/2003, 14:48
Avatar de AlZuwaga
Colaborador
 
Fecha de Ingreso: febrero-2001
Ubicación: 34.517 S, 58.500 O
Mensajes: 14.550
Antigüedad: 23 años, 3 meses
Puntos: 535
respondo rápida y escuetamente por el momento porque no tengo mucho tiempo:

Al final hice "la gran joanco" (el instr por cada elemento del arreglo de menor tamaño) y anda de maravillas. Hasta simulando la peor situación (2169 comparaciones) y demora prácticamente nada.

Ahora estoy teniendo otros problemas pero los atribuyo a que como hoy es viernes estoy con la cabeza en otro lado y ya no puedo pensaaaarrr!!!!

nos vemos
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 21:55.