elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Problema con mapas
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Problema con mapas  (Leído 3,816 veces)
Orubatosu


Desconectado Desconectado

Mensajes: 2.515


Ver Perfil WWW
Problema con mapas
« en: 19 Diciembre 2014, 16:28 pm »

Tengo un curioso problema que me esta mareando un poco, os explico:

Código:

int main(){
    string entrada;
    map <int, bool> A;
    map <int, bool> B;
    getline (cin, entrada);
    cout << entrada << endl;
    A = separa (entrada);
    while (getline (cin, entrada)){
        B = separa (entrada);
        map<int, bool>::iterator it = A.begin();
        for (; it != A.end(); it++){
            map<int, bool>::iterator itb = B.find(it->first);
            if (itb == B.end()){
                A.erase(it->first);
                map<int, bool>::iterator it = A.begin();
            }
        }
        muestra (A);
    }
}


Omito las funciones y cabeceras, se que funcionan y no me dan problemas, y aclaro un poco este follón de código.

Lo que hago, es capturar secuencias de enteros y filtrar solo los que aparecen en todas las líneas. Mi idea es capturar una linea y meterla en un mapa (Mapa A), las siguientes en el mapa "B".

Luego, itero el mapa "A" y compruebo si la llave del iterador existe en el mapa "B", y en caso de que no sea así, borro de A esa clave.

El caso es que el programa, tal y como está "revienta". Solo puedo asumir que tengo un iterador "loco" corriendo por ahi, pero no acabo de ver cual, porque veamos:

Tengo un iterador "it" que va a recorrer los valores del mapa A, y lo ubico en su primera casilla. Luego, compruebo con el iterador ITB si el valor de la llave de ese iterador existe en "B", si el valor devuelto es "B.end" entonces es que no está, por lo que borro ese contenido en "A".
Soy consciente desde luego, que desde el momento en que efectuo una operación de borrado, ese iterador deja de ser valido, por lo que lo devuelvo a su punto inicial, pero vamos... no se porque "explota"

Estoy pensando obviamente en no borrar nada, y usar el valor asociado a la clave (que es booleano) para marcarlo, y ya os diré como va la cosa, pero claro, el tema es que si quisiera borrar datos, me veo ante un código que falla, y no tengo claro porque.

A ver si alguien ve donde estoy metiendo la gamba

Por cierto, si hago eso que os he comentado, el programa funciona... os pongo el código entero por si alguien quiere aclararse un poco mas


Código:
#include <iostream>
#include <sstream>
#include <map>
using namespace std;

map <int, bool> separa (string& s){
    istringstream S (s);
    map<int, bool> ret;
    int n;
    while (S >> n){
        ret[n] = false;
    }
    return ret;
}

void muestra (const map<int, bool>& m){
    map<int, bool>::const_iterator itm = m.begin();
    for (; itm != m.end(); itm++){
        if (itm->second == false) cout << itm->first << ' ';
    }
    cout << endl;
}

int main(){
    string entrada;
    map <int, bool> A;
    map <int, bool> B;
    getline (cin, entrada);
    cout << entrada << endl;
    A = separa (entrada);
    while (getline (cin, entrada)){
        B = separa (entrada);
        map<int, bool>::iterator it = A.begin();
        for (; it != A.end(); it++){
            map<int, bool>::iterator itb = B.find(it->first);
            if (itb == B.end()){
                it->second = true;
            }
        }
        muestra (A);
    }
}

Claro, el programa ahora va, pero sigo sin saber porque la versión anterior que borraba los elementos no repetidos no lo hace, y preferiría saber porque es eso, antes que pensar "buenooooo ahora funciona, no me preocupo mas"


« Última modificación: 19 Diciembre 2014, 16:33 pm por Orubatosu » En línea

"When People called me freak, i close my eyes and laughed, because they are blinded to happiness"
Hideto Matsumoto 1964-1998
avesudra


Desconectado Desconectado

Mensajes: 724


Intentando ser mejor cada día :)


Ver Perfil
Re: Problema con mapas
« Respuesta #1 en: 19 Diciembre 2014, 17:10 pm »

Hola Orubatosu, sin ver bien donde revienta el programa, solo veo que estas declarando un iterador nuevo y no modificando el existente al volver it a la posición inicial, es decir aquí:

Código
  1. if (itb == B.end())
  2. {
  3.    A.erase(it->first);
  4.    map<int, bool>::iterator it = A.begin();
  5. }

Si no me equivoco debería ser:
Código
  1. if (itb == B.end())
  2. {
  3.    A.erase(it->first);
  4.    it = A.begin();
  5. }

Ya que ese iterador solo está definido en ese ámbito, y elimina la visibilidad del iterador it que declaraste antes y evidentemente no modificas el valor del que quieres modificar. Por tanto el iterador it original no vuelve a la posición inicial nunca.

Hay otro problema y es que cuando modificas eso(si no lo modificas con la misma entrada te da un error de violación de acceso a la memoria) y pulsas intro se crea un bucle infinito (no sé donde está el fallo). Para comprobarlo puedes usar la siguiente entrada:
Código:
1
Salida de la funcion muestra: 1
2
Bucle infinito

Saludos.


« Última modificación: 19 Diciembre 2014, 18:00 pm por avesudra » En línea

Regístrate en
Orubatosu


Desconectado Desconectado

Mensajes: 2.515


Ver Perfil WWW
Re: Problema con mapas
« Respuesta #2 en: 19 Diciembre 2014, 18:02 pm »

Vale... el problema era tan "simple" como eso, el iterador ya estaba definido, y al redifinirlo la lio.

Hare un par de experimentos a ver, aunque el programa en realidad funciona sin borrar nada, pero quiero tener claro que hacer en caso de que SI quiera borrar, o no liarla con los iteradores.

Lo cómico es que al borrar el elemento que apunta al iterador, este se quede "en el aire", debería (pienso yo) o desaparecer o reubicarse en otra posición, pero no quedarse "ahi colgado"
En línea

"When People called me freak, i close my eyes and laughed, because they are blinded to happiness"
Hideto Matsumoto 1964-1998
avesudra


Desconectado Desconectado

Mensajes: 724


Intentando ser mejor cada día :)


Ver Perfil
Re: Problema con mapas
« Respuesta #3 en: 19 Diciembre 2014, 18:04 pm »

Vale... el problema era tan "simple" como eso, el iterador ya estaba definido, y al redifinirlo la lio.

Hare un par de experimentos a ver, aunque el programa en realidad funciona sin borrar nada, pero quiero tener claro que hacer en caso de que SI quiera borrar, o no liarla con los iteradores.

Lo cómico es que al borrar el elemento que apunta al iterador, este se quede "en el aire", debería (pienso yo) o desaparecer o reubicarse en otra posición, pero no quedarse "ahi colgado"

Pero ahora da un error mas raro todavía, hace un bucle infinito muy muy raro, no sé que puede estar pasando.

Saludos.
En línea

Regístrate en
Orubatosu


Desconectado Desconectado

Mensajes: 2.515


Ver Perfil WWW
Re: Problema con mapas
« Respuesta #4 en: 19 Diciembre 2014, 18:34 pm »

Pues no lo se... acabo de intentar la modificación que propones, y ahora funciona correctamente, borrando y sin "volar" el programa  :huh:

Ten en cuenta que la función "mostrar" no es igual en ambas versiones, inicialmente solo saco los valores de las claves (ignorando los valores asociados), mientras que en la segunda he modificado esa función (y no te lo he comentado  :-X)

Yo así veo que funciona

Código:
#include <iostream>
#include <sstream>
#include <map>
using namespace std;

map <int, bool> separa (string& s){
    istringstream S (s);
    map<int, bool> ret;
    int n;
    while (S >> n){
        ret[n] = false;
    }
    return ret;
}

void muestra (const map<int, bool>& m){
    map<int, bool>::const_iterator itm = m.begin();
    for (; itm != m.end(); itm++){
        cout << itm->first << ' ';
    }
    cout << endl;
}

int main(){
    string entrada;
    map <int, bool> A;
    map <int, bool> B;
    getline (cin, entrada);
    cout << entrada << endl;
    A = separa (entrada);
    while (getline (cin, entrada)){
        B = separa (entrada);
        map<int, bool>::iterator it = A.begin();
        for (; it != A.end(); it++){
            map<int, bool>::iterator itb = B.find(it->first);
            if (itb == B.end()){
                A.erase(it->first);
                it = A.begin();
            }
        }
        muestra (A);
    }
}

En línea

"When People called me freak, i close my eyes and laughed, because they are blinded to happiness"
Hideto Matsumoto 1964-1998
avesudra


Desconectado Desconectado

Mensajes: 724


Intentando ser mejor cada día :)


Ver Perfil
Re: Problema con mapas
« Respuesta #5 en: 19 Diciembre 2014, 19:11 pm »

Pues no lo se... acabo de intentar la modificación que propones, y ahora funciona correctamente, borrando y sin "volar" el programa  :huh:

Ten en cuenta que la función "mostrar" no es igual en ambas versiones, inicialmente solo saco los valores de las claves (ignorando los valores asociados), mientras que en la segunda he modificado esa función (y no te lo he comentado  :-X)

Yo así veo que funciona

Que va a mi no me va, mete primero un 1 y luego un 2, verás como al intentar meter otro valor no te deja :S

Un saludo.
En línea

Regístrate en
Orubatosu


Desconectado Desconectado

Mensajes: 2.515


Ver Perfil WWW
Re: Problema con mapas
« Respuesta #6 en: 19 Diciembre 2014, 19:19 pm »

Errr... a ver, es que esa no es la idea del programa

La idea del programa es que pongas una secuencia de numeros, tal que así

1 2 3 5 8 9 7 5 8 21 55 33 22 7 -10 25 (intro)
5 7 25 13 8 22 (intro)
1 2 5 9 78 22 (intro)

Y va diciéndote los números que están en todas las líneas

Si metes solo un numero, y luego otro, obviamente ya no importa lo que pongas, todo lo que introduzcas a partir de ahí no aparece en todas las líneas.

Claro, no he puesto medidas para evitar un uso "diferente" porque solo estoy haciendo problemas sin mirar de evitar este tipo de cosas

La "idea" es un programa que filtre secuencias diferentes y mantenga solo los números que aparecen en todas las entradas
En línea

"When People called me freak, i close my eyes and laughed, because they are blinded to happiness"
Hideto Matsumoto 1964-1998
avesudra


Desconectado Desconectado

Mensajes: 724


Intentando ser mejor cada día :)


Ver Perfil
Re: Problema con mapas
« Respuesta #7 en: 19 Diciembre 2014, 19:20 pm »

Ahhh entonces solucionado.

Un saludo  ;D
En línea

Regístrate en
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Mapas
Programación Visual Basic
ranslsad 3 1,947 Último mensaje 13 Abril 2007, 00:23 am
por ranslsad
MAPAS COD 5 PS3
Juegos y Consolas
toninoo 2 2,985 Último mensaje 20 Junio 2009, 19:50 pm
por toninoo
Problema de mapas en el Counter Strike 1.6
Juegos y Consolas
Br1ant 0 2,730 Último mensaje 4 Marzo 2014, 00:33 am
por Br1ant
problema con mapas gps SMEG+
Dispositivos Móviles (PDA's, Smartphones, Tablets)
txanto 0 3,309 Último mensaje 9 Abril 2016, 09:18 am
por txanto
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines