Pagini: [1]   În jos
  Imprimă  
Ajutor Subiect: Ciudat  (Citit de 2663 ori)
0 Utilizatori şi 1 Vizitator pe acest subiect.
APOCALYPTO
Nu mai tace
*****

Karma: 3
Deconectat Deconectat

Mesaje: 250



Vezi Profilul
« : Iunie 22, 2010, 14:39:14 »

Am scris o sursa pentru problema Gmin max si se intampla ceva ciudat cu bucata urmatoare de cod
 
Cod:
      for(it=G[bex].begin();it!=G[bex].end();it++)//pentru toti vecinii lui bex
        {vector<int>::iterator it1;
            for(it1=G[*it].begin();it1!=G[*it].end();it1++) // cauta-l pe bex intre vecinii lui *it ca sa-l
            {
            if(*it1==bex) //stergi si sa micsorezi gradul lui *it si sa updatezi heapul  :-'
            {
            G[*it].erase(it1);
            g[*it]--;
            upheap(poz[*it]);
            }
            }
        }
si am observat ca programul pur si simplu nu se oprea la G[*it].end(); si cicla pana cand probabil it ajungea intr-un spatiu de memorie nealocata.
apoi am inlocuit cu

Cod:
        for(it=G[bex].begin();it!=G[bex].end();it++)
        {vector<int>::iterator it1;
            for(it1=G[*it].begin();it1-G[*it].begin()+1<=g[*it];it1++)
            {
            if(*it1==bex)
            {
            G[*it].erase(it1);
            g[*it]--;
            upheap(poz[*it]);
            }
            }
            
        }
unde g[ i ] repezinta numarul de vecini ai nodului i si am luat 100.
Are cineva idee ce s-a intamplat?
Memorat
Florian
Nu mai tace
*****

Karma: 125
Deconectat Deconectat

Mesaje: 832



Vezi Profilul
« Răspunde #1 : Iunie 22, 2010, 14:59:54 »

Din cauza ca faci G[*it].erase(it1);
Memorat
APOCALYPTO
Nu mai tace
*****

Karma: 3
Deconectat Deconectat

Mesaje: 250



Vezi Profilul
« Răspunde #2 : Iunie 22, 2010, 16:37:22 »

Din cauza ca faci G[*it].erase(it1);

Ok dar fac asta la ambele surse. Si pe deasupra cum as putea elimina un element din vector in afara de a folosi erase?
Memorat
BitOne
Strain
*

Karma: -1
Deconectat Deconectat

Mesaje: 45



Vezi Profilul
« Răspunde #3 : Iunie 22, 2010, 16:54:10 »

Dupa fiecare stergere trebuie sa dereferentiezi iteratorul altfel poti avea niste surprize foarte urate. Alta functie ar fi remove.
Daca G[*it] are un singur element si acesta este egal cu bex ?  Il stergi si vectorul devine vid, apoi mai dai si cu ++it1 pentru incrementare ce rezulta la un Kill by signal 11.
Memorat
APOCALYPTO
Nu mai tace
*****

Karma: 3
Deconectat Deconectat

Mesaje: 250



Vezi Profilul
« Răspunde #4 : Iunie 22, 2010, 17:38:11 »

Dupa fiecare stergere trebuie sa dereferentiezi iteratorul altfel poti avea niste surprize foarte urate. Alta functie ar fi remove.
Daca G[*it] are un singur element si acesta este egal cu bex ?  Il stergi si vectorul devine vid, apoi mai dai si cu ++it1 pentru incrementare ce rezulta la un Kill by signal 11.
Deci atunci cand parcurg un vector din care sterg si elemente cel mai corect este sa fac ca mai sus sau asa:
Cod:
       for(it=G[bex].begin();it!=G[bex].end();it++)
        {vector<int>::iterator it1;
            for(it1=G[*it].begin();!(it1>=G[*it].end());it1++)
            {
            if(*it1==bex)
            {int bahh;
            G[*it].erase(it1);
            g[*it]--;

            bahh=poz[*it];

            upheap(bahh);

            }
            }

        }
?
Memorat
BitOne
Strain
*

Karma: -1
Deconectat Deconectat

Mesaje: 45



Vezi Profilul
« Răspunde #5 : Iunie 22, 2010, 17:45:32 »

Cel mai corect este
Cod:
G[*it].erase(it1);
it1=G[*it].begin();
Daca vrei poti folosi remove_if
Memorat
APOCALYPTO
Nu mai tace
*****

Karma: 3
Deconectat Deconectat

Mesaje: 250



Vezi Profilul
« Răspunde #6 : Iunie 22, 2010, 17:52:13 »

Cel mai corect este
Cod:
G[*it].erase(it1);
it1=G[*it].begin();
Daca vrei poti folosi remove_if
Pai da dar nu sterg  incepand cu primul element mereu.
Si daac folosesc remove_if mai merge sa scad gradele:(?
Memorat
BitOne
Strain
*

Karma: -1
Deconectat Deconectat

Mesaje: 45



Vezi Profilul
« Răspunde #7 : Iunie 22, 2010, 17:56:25 »

Eu am scris doar o bucata de cod, odata ce ai sters un element o ei de la inceput nu continui cu ++it   Wink
LE: Da merge, pui in functie ce tre sa faca ....
Cod:
inline bool TobeRemoved( int x )
{
        if( x == with_something )
       {
                 do something;
                 return true;
        }
        return false;
}
//apelzi asa :
vector< int >::iterator new_end=remove_if( v.begin(), v.end(), TobeRemoved ); /*va sterge toate elementele pt face TobeRemoved(x) == true. Noul "sfarsit" al vectorului este new_end */
« Ultima modificare: Iunie 22, 2010, 18:17:23 de către SAlexandru » Memorat
APOCALYPTO
Nu mai tace
*****

Karma: 3
Deconectat Deconectat

Mesaje: 250



Vezi Profilul
« Răspunde #8 : Iunie 22, 2010, 18:09:02 »

Eu am scris doar o bucata de cod, odata ce ai sters un element o ei de la inceput nu continui cu ++it   Wink

Am inteles dar in conditii de concurs iti dai seama cat timp pierzi  sad?
Memorat
BitOne
Strain
*

Karma: -1
Deconectat Deconectat

Mesaje: 45



Vezi Profilul
« Răspunde #9 : Iunie 22, 2010, 18:14:51 »

Am inteles dar in conditii de concurs iti dai seama cat timp pierzi  sad?
Prefer TLE decat Kill by Signal 11  Wink) ( adica sa mearga dar nu optim, decat optim si sa crape )
Oricand poti folosi liste simplu inlantuite, chiar si din STL cred ( n-am incercat ).
Memorat
Pagini: [1]   În sus
  Imprimă  
 
Schimbă forumul:  

Powered by SMF 1.1.19 | SMF © 2006-2013, Simple Machines