Iterowanie po mapie dwuwymiarowej

0

Witam, stworzyłem taką mapę

map <long int, map <long int, long int> > neighbors;

O ile wiem jak iterować po mapie jednowymiarowej za pomocą iteratora to już z dwu mam problem. Podejrzewam że to będzie coś w stylu zwykłych tablic (2 fory), tylko nie bardzo wychodzi. Nie wiem jak te iteratory dobrze ustawić.

Pozdrawiam

0

Pokaż jak ci "nie wychodzi", wskażemy gdzie jest błąd.

0

np tak:

    map <long int, map <long int, long int> > neighbors; //A - B - dist(A, B)
    map <long int, map <long int, long int> >::iterator it;
    map <long int, long int>::iterator bit;
    
    for(bit=neighbors.begin(); bit!=neighbors.end(); bit++) {
    for(it=neighbors[bit.begin()]; it!=neighbors[bit.end()]; it++)
    {
    }
}


i inne wariacje tego typu.. no ale wiem że to nie będzie raczej działać

0
    map <long int, map <long int, long int> > neighbors; //A - B - dist(A, B)
    map <long int, map <long int, long int> >::iterator it;
    map <long int, long int>::iterator bit;
 
    for(it=neighbors.begin(); it!=neighbors.end(); it++) {
    for(bit=it->second.begin(); bit!=it->second.end(); bit++)
    {
    }
}

nie zauważyłem na początku, że oprócz tego, że masz oprócz logicznego błędu iteratory bit i it zamienione

0

Dzięki faktycznie teraz działa

A co źle tu napisałem?


//klasa jakas
Tmatrix * Parser::get_graph_matrix()
{
    return &this->graph_matrix;
}

Tnodes * Parser::get_nodes()
{
    return &this->nodes;
}

//main.cpp
    OGraph = new Graph(OParser->get_graph_matrix(), OParser->get_nodes());

class Graph
{
    public:
    
    Tmatrix * graph_matrix;
    Tnodes * graph_nodes;
    
    Graph(Tmatrix * graph_matrix, Tnodes * graph_nodes); 
    void get_shortest_way(string street_name1, string street_name2);
    
    private:
    
    void Dijkstra(long int A, long int B);
    long int get_node_id(string street_name); 
};

Graph::Graph(Tmatrix * graph_matrix, Tnodes * graph_nodes)
{
    this->graph_matrix = graph_matrix;
    this->graph_nodes  = graph_nodes;
}

//this->graph_nodes to mapa
long int Graph::get_node_id(string street_name)
{
    Tnodes::iterator it; //map <long int, Graph_node*>
    
    for(it = this->graph_nodes.begin(); it != this->graph_nodes.end(); it++)
    {
	if(it->second->street_name == street_name)
	    return it->first;
    }
}

że wywala błąd

In file included from main.cpp:18:0:
classes/class.graph.cpp: In member function ‘long int Graph::get_node_id(std::string)’:
classes/class.graph.cpp:27:32: error: request for member ‘begin’ in ‘((Graph*)this)->Graph::graph_nodes’, which is of non-class type ‘Tnodes* {aka std::map<long int, Graph_node*>*}’
classes/class.graph.cpp:27:65: error: request for member ‘end’ in ‘((Graph*)this)->Graph::graph_nodes’, which is of non-class type ‘Tnodes* {aka std::map<long int, Graph_node*>*}’
0
graph_nodes.begin()

------->graph_nodes->begin()

 i analogicznie z end.
0

Dzięki faktycznie... tylko dlaczego w tej metodzie straciłem możliwość odwoływania się za pomocą this?

 cout<<this->graph_nodes[880402574]->street_name; 

wyrzuca że to nie pointer-type a przecież przypisałem elegancko wszystko jak wyżej

1

Ponieważ teraz graph_nodes to wskaźnik

 cout<<*(this->graph_nodes)[880402574]->street_name; 
0

Chyba jednak nie, bo tak próbowałem i ten sam błąd.
//edit
ok wystarczyło dać w konstruktorze gwiazdke do tych argumentow przy przypisaniu ;]

0

Tylko jest taki problem że ta pętla nie wyświetla wszystkich nodów... tzn powyższy przykład z kluczem 88... wyświetla ulicę Komandosów, natomiast jak wyświetlam wszystkie ulice w pętli to tej ulicy nie ma.. dodatkowo wywala naruszenie ochrony pamięci...

0

Proszę oto trochę więcej kodu:

//klasa parser pliku (czesc metody)
//......
	if(line.substr(0, 5) == "<node") 
	{
	    Graph_node * ONodes;
	    ONodes = new Graph_node;
	    ONodes->lat = to_float((this->get_value("lat", line))[0]);
	    ONodes->lon = to_float((this->get_value("lon", line))[0]);
	    ONodes->id = node_id;
	    this->nodes[to_lint((this->get_value("id", line))[0])] = ONodes;   
//wyluskuje tutaj z tagow w pliku <node id="liczba"...> ta liczbe jako id i tworze na jej podstawie mape obiektow   
	    node_id++;	
	}	
	
	if(line.size() >= 6)
	{
	    if(line.substr(0, 4) == "<way" || start_way == true) //w drugiej czesci pliku sa <way> <nd ref="liczba"><tag k="nazwa_ulicy">, liczba to id node'a,
	    {
		new_line = new_line + line;	
		start_way = true;	 
	    }
	    
	    if(line.substr(0, 6) == "</way>")
	    {
		string street_name;
		vector <string> keys = get_value("k", new_line);
				
		nds = this->get_value("ref", new_line);
		
		for(int i=0; i<keys.size(); i++) 
		{
		    if(keys[i] == "name")
		    {    
			street_name = (this->get_value("v", new_line))[i];
			break;
		    }
		}	
			//do tej pory mam elegancko wszystkie street name
		for(int i=0; i<nds.size(); i++)
		{		   
		    if(this->nodes[to_lint(nds[i])]) //jesli node z way'a istnieje (bo nie wszystkie ref="liczba" istnieją w nodach bo to tylko fragment pliku)
		    {			
			exist_nds.push_back(to_lint(nds[i])); //to te co istnieja do vectora
		    } 
		}
		// jak tu dam cout<<street_name to wyswietla poprawnie
		for(int i=0; i<exist_nds.size(); i++)
		{
		    if(i < exist_nds.size()-1)
		    {
			if(street_name == "") street_name = "<no named>"; 
			
			this->nodes[exist_nds[i]]->street_name = street_name; //i do tych istniejacych przypisuje street name
			double ab_dist = gdistance(this->nodes[exist_nds[i]]->lat, this->nodes[exist_nds[i]]->lon, this->nodes[exist_nds[i+1]]->lat, this->nodes[exist_nds[i+1]]->lon);
			this->graph_matrix[exist_nds[i]][exist_nds[i+1]] = ab_dist;
			this->graph_matrix[exist_nds[i+1]][exist_nds[i]] = ab_dist;
	            }		    
		}
	
		nds.clear();
		exist_nds.clear();
		street_name.clear();
		new_line.clear();
		start_way = false;
		
	    }
//......


//zwracanie tych graph_matrix i nodes

Tmatrix * Parser::get_graph_matrix()
{
    return &(this->graph_matrix);
}

Tnodes * Parser::get_nodes()
{
    return &(this->nodes);
}

//main.cpp

    OGraph = new Graph(OParser->get_graph_matrix(), OParser->get_nodes());

//klasa graph

class Graph
{
    public:
    
    Tmatrix graph_matrix;
    Tnodes graph_nodes;
    
    Graph(Tmatrix * graph_matrix, Tnodes * graph_nodes); 
    void get_shortest_way(string street_name1, string street_name2);
    long int get_node_id(string street_name);
    private:
    
    void Dijkstra(long int A, long int B);
     
};

Graph::Graph(Tmatrix * graph_matrix, Tnodes * graph_nodes)
{
    this->graph_matrix = *graph_matrix;
    this->graph_nodes  = *graph_nodes; 
}

long int Graph::get_node_id(string street_name)
{
    Tnodes::iterator it;

    for(it = this->graph_nodes.begin(); it != this->graph_nodes.end(); it++)
    {
	if(it->second->street_name == street_name) 
	    return it->first; 
    }
   
}

Kompiluje sie, ale nie wyswietla wszystkich ulic i na koniec dostaje NAruszenie ochrony pamieci. WLasciwie w tej pierwszej metodzie do ostatniej linijki jest wszystko wporzadku, problem jest w tym iteratorze przy wysiwetlaniu

1

Czy wiesz o tym, że w C++ nie trzeba uzywać this? Jeżeli bardzo chcesz zaznaczyć, że coś jest polem to ładniejsze wg mnie jest konsekwetne poprzedzanie nazwy m_ (choć konwencji tutaj jest sporo)

Po drugie, zdecydowanie za dużo wskaźników.

Po trzecie, sprawdź, czy we wszystkich klasach, w których alokujesz pamięć dynamicznie, masz destruktor, konstruktor kopiujący i operator przypisania.

Edit: Jeszcze jedno, jeżeli w środku funkcji na pewien fragment dajesz komentarz, co on robi, to pewnie powinno to być w osobnej funkcji.

1 użytkowników online, w tym zalogowanych: 0, gości: 1