[C++] Błędnie działająca pętla for z iteratorem (pair) 6084 7

O temacie

Autor Wonski

Zaczęty 18.04.2015 roku

Wyświetleń 6084

Odpowiedzi 7

Wonski

Wonski

Gry (themodders@telegram)
radio engineer
posty256
Propsy91
ProfesjaProgramista
  • Gry (themodders@telegram)
  • radio engineer
#include <iostream>
#include <list>
#include <queue>
#include <vector>
#include <utility> //biblioteka potrzebna do tworzenia par

using namespace std;

struct vertex
{
    int kolor;
    int odleglosc;
    int rodzic;
};

typedef struct pair < int, int > para;

int main()
{
    cout << "Ile wierzcholkow w grafie? ";
    int rozmiar;
    cin >> rozmiar;
   
    vertex wierzcholek[ rozmiar + 1 ];
    list < para > graph[ rozmiar + 1 ];
   
    queue < int > kolejka;
   
    cout << "Ile krawędzi: ";
    int m;
    cin >> m;
   
    //przypisywanie polaczen
    for( int i = 1; i <= m; i++ )
    {
        int v1, v2, weight;
        cin >> v1 >> v2 >> weight;
        para pair1 = make_pair( v2, weight );
        graph[ v1 ].push_back( pair1 );
    }
   
    //wyswietlanie sasiadow
   
    /*
      for(int i = 1; i <= rozmiar; i++)
      {
        cout << i << ": ";
   
        // ta petla odpowiada za wyswietlanie wierzcholkow docelowych
        // ta petla moze dzialac jako wizualizacja list sasiedztwa
   
          for(list<para>::iterator j = graph[i].begin(); j != graph[i].end(); j++)
          {
            cout << j -> first << "#" << j -> second << " ";   
          }
   
        // ta petla odpowiada za wyswietlanie wierzcholkow wyjsciowych
        // ta petla powinna dzialac osobno (bez pierwszej petli for) dla grafu nieskierowanego
   
          int act, example;
          act = i;
          for(int w=act; w>=1; w--)
          {
            for(list<para>::iterator j = graph[w].begin(); j != graph[w].end(); j++)
            {
            if(j->first == i)
            cout << w << " ";
            }
          }
   
   
        cout << endl;
        }
    */
   
    //PRZESZUKIWANIE WSZERZ
   
    cout << endl << "Podaj zrodlowy wierzcholek: ";
    int root;
    cin >> root;
   
    for( int i = 1; i <= rozmiar; i++ )
    {
        wierzcholek[ i ].kolor = 0; //0 = bialy
        wierzcholek[ i ].odleglosc = 0;
        wierzcholek[ i ].rodzic = 0;
    }
    wierzcholek[ root ].kolor = 1; //1 = szary
    wierzcholek[ root ].odleglosc = 0;
    wierzcholek[ root ].rodzic = 0;
   
    kolejka.push( root );
    int obecny;
    while( kolejka.empty() == false )
    {
        obecny = kolejka.front();
        kolejka.pop();
        //for(int k=1; k<=graph[obecny].size(); k++)
        //{
       
        for( list < para >::iterator j = graph[ obecny ].begin(); j != graph[ obecny ].end(); j++ )
        {
            if( wierzcholek[ j->first ].kolor == 0 )
            {
                wierzcholek[ j->first ].kolor = 1;
                wierzcholek[ j->first ].odleglosc = wierzcholek[ obecny ].odleglosc + 1;
                wierzcholek[ j->first ].rodzic = obecny;
                kolejka.push( j->first );
            }
            wierzcholek[ obecny ].kolor = 2; //2 = czarny
        }
        //}
    }
   
    cout << endl << endl;
    for( int i = 1; i <= rozmiar; i++ )
         cout << i << ": " << wierzcholek[ i ].odleglosc << endl;
   
    return 0;
}

Wkleiłem cały kod ponieważ uważam, że aby zrozumieć co mam na myśli należy zerknąć na kod całego programu.
Mój problem dotyczy sekcji "przeszukiwanie wszerz" a dokładniej pętli ze zmienną j. Pętla zachowuje się tak jakby odwoływała się do licznika pary w której mamy dwa elementy, co jest oczywiście błędem.

Taki sam problem miałem w sekcji wyświetlanie sąsiadów. W rozwiązaniu problemu pomogły pętle poprzedzające pętle z iteratorem. W taki sam sposób chciałem rozwiązać problem w "przeszukiwaniu" (stosując pętlę ze zmienną k) lecz nic to nie dało.

Wracając do problemu. Chcę aby pętla z iteratorem j (w sekcji przeszukiwanie wszerz) liczyła ilość elementów listy, bo w tym momencie liczy ilość elementów w pair.

Proszę powiedzieć co robię źle i w jaki sposób można by rozwiązać ten problem.
Mam nadzieję, że wszystko jasno opisałem.
Pozdrawiam i czekam na odpowiedź.

Przepraszam za copypast z cpp0x, ale tam niestety nikt nie potrafił mi pomóc  :redface:
 

mgr Fartuess

mgr Fartuess

Użytkownicy
Kiedyś to były czasy!
posty1485
Propsy890
ProfesjaProgramista
  • Użytkownicy
  • Kiedyś to były czasy!
C++11? Jeśli tak, to możesz zastąpić
for( list < para >::iterator j = graph[ obecny ].begin(); j != graph[ obecny ].end(); j++ )na
for (para j : graph)
Robi to samo a jest przejrzystsze.

Co do samego problemu to jeszcze popatrzę.

Edit:
To jest wyszukiwanie ścieżek na kratce kwadratowej przy użyciu przeszuwiania wszerz tak? W takim razie gdzie bierzesz sąsiadów verta na którym pracujesz?
 
Popisuje się ciągle menda jedna...

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
Cytuj
Wracając do problemu. Chcę aby pętla z iteratorem j (w sekcji przeszukiwanie wszerz) liczyła ilość elementów listy, bo w tym momencie liczy ilość elementów w pair.
Jeśli dobrze zrozumiałem, to wystarczy tam użyć:
graph[obecny].size();Aha, i nie ilość, tylko liczba.

Albo podaj przykładowe dane i wyniki, może wtedy zrozumiem o co tu chodzi. :D

Wonski

Wonski

Gry (themodders@telegram)
radio engineer
posty256
Propsy91
ProfesjaProgramista
  • Gry (themodders@telegram)
  • radio engineer
Adanos
Twoim sposobem odwoływałbym się do elementu listy graph, którym jest struktura pair a w strukturze pair nie ma metody size, bo z
góry wiadomo, że są tam tylko 2 elementu.
Dane wejściowe
Wpierw zapełniamy graf:
7
10
1 3 3
1 5 2
2 3 5
2 5 1
2 6 3
3 4 1
3 6 9
4 5 3
4 7 5
6 7 4
niech wierzchołkiem źródłowym będzie 7, więc:
(Dane wyjściowe dla sekcji przeszukiwanie wszerz)
1: 3
2: 3
3: 2
4: 1
5: 2
6: 1
7: 0   


Fartuess

Jest to zwykłe przeszukiwanie wszerz grafu opartego na reprezentacji listowej z własną definicją wierzchołka. W sumie jest to trochę hybryda, ponieważ poprzez strukturę vertex nie mam "podręcznikowej" złożoności pamięciowej i obliczeniowej... jednak coś za coś... dzięki własnej definicji mogę mieć dowolną ilość atrybutów, co z całą pewnością przyda się przy projektowaniu innych algorytmów.
Wracając do Twojego pytania...
Obecny vetrex jest określony przez zmienną "obecny". Dalej w tej cholernej pętli chciałem liczyć ilość elementów na liście o numerze "obecny" a samym iteratorem j operować na kolejnych elementach listy (sąsiadach).
Jak już pisałem, analogiczne pętle stosowałem w sekcji "wyświetlanie sąsiadów" i tam działają bez zarzutu...
 

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
Źle tworzysz listę sąsiedztwa.
//przypisywanie polaczen
    for( int i = 1; i <= m; i++ )
    {
        int v1, v2, weight;
        cin >> v1 >> v2 >> weight;
        para pair1 = make_pair( v2, weight );
        graph[ v1 ].push_back( pair1 );
    }
Powinieneś jeszcze dodać:
graph[ v2 ].push_back( make_pair( v1, weight ));
Cytuj
Twoim sposobem odwoływałbym się do elementu listy graph, którym jest struktura pair a w strukturze pair nie ma metody size, bo z
góry wiadomo, że są tam tylko 2 elementu.
Nieprawda. Odwoływałbyś się do elementu o indeksie obecny w liście.

Wonski

Wonski

Gry (themodders@telegram)
radio engineer
posty256
Propsy91
ProfesjaProgramista
  • Gry (themodders@telegram)
  • radio engineer
Nieprawda. Odwoływałbyś się do elementu o indeksie obecny w liście.

Odwołuję się do elementu listy. Przecież lista przechowuje elementy typu pair. A w pair nie ma metody size.
Czegoś tu nie rozumiem.
Zresztą zaraz sprawdzę i wieczorem dam odpowiedź
 

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
Sam zobacz:


Tak naprawdę masz tablicę, która w każdym elemencie ma listę.

mgr Fartuess

mgr Fartuess

Użytkownicy
Kiedyś to były czasy!
posty1485
Propsy890
ProfesjaProgramista
  • Użytkownicy
  • Kiedyś to były czasy!
Czyli tam jednak gdzieś jest definiowanie sąsiedztwa? Czytałem fragment do którego mnie odesłano a jako, że nie ma tu rozbicia nawet na funkcje ( ! ), to beznadziejnie się to czyta.
 
Popisuje się ciągle menda jedna...


0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry