2016-08-15 67 views
2

我有一個2D地圖聲明動態分配到一個二維的std :: unordered_map

unordered_map< string, unordered_map<string, Road*>* > matrix; 

這需要的

class Road { 
public: 
    Road() : connected(0), weight(0) {} 

    bool connected; 
    int weight; 
}; 

路的實例,我分配如下

void addPlace(string place) { 
    // error checking 
    if (placeExists(place)) { 
     cout << "Place already exists" << endl; 
     return; 
    } 

    Road *road = new Road(); 
    unordered_map<string, Road*> *newRelationship = new unordered_map<string, Road*>; 
    newRelationship->insert({ {place},{road} }); 

    // add to network 
    matrix.insert({ { place },{ newRelationship } }); 
    ++n_verticies; 
} 

但是,當我撥打

void connectPlace(string source, string dest, int w) 
    if (!placeExists(dest) || !placeExists(source)) { 
     cout << "Place(s) does not exists" << endl; 
     return; 
    } 
    ... 
    if (matrix.find(source)->second->find(dest)->second->connected) 

我收到一個錯誤:「列表迭代器不可解引用」,這表明我已經在我的分配出錯了地方?先謝謝你。

這是我的呼籲placeExists,從connectPlace返回true兩個電話:

bool placeExists(string place) { 
    if (matrix.find(place) == matrix.end()) { 
     return false; 
    } 
    return true; 
} 

我已經打破下來到

auto a = matrix.find(source); 
    auto b = matrix.find(source)->second; 
    auto c = matrix.find(source)->second->find(dest); // (<Error reading characters of string.>, {connected=??? weight=??? }) 
    auto d = matrix.find(source)->second->find(dest)->second; // stops here 
    auto e = matrix.find(source)->second->find(dest)->second->connected; 

我的函數調用如下

Graph *road_network = new Graph(false); 

road_network->addPlace("Sacremento"); 
road_network->addPlace("Antelope"); 
road_network->addPlace("Roseville"); 
road_network->addPlace("San Francisco"); 
road_network->addPlace("San Jose"); 
road_network->addPlace("Davis"); 
road_network->addPlace("Los Angelous"); 

road_network->connectPlace("Sacremento", "Antelope", 5); //<-- break 
road_network->connectPlace("San Francisco", "San Jose", 2); 
road_network->connectPlace("Los Angelous", "Davis", 10); 
road_network->connectPlace("Davis", "Antelope", 4); 
road_network->connectPlace("Roseville", "Davis", 5); 
road_network->connectPlace("San Jose", "Antelope", 6); 
road_network->connectPlace("Davis", "Los Angelous", 5); 
+0

'matrix.find(source) - > second-> find(dest) - > second-> connected'這在一行中做了太多事情。我建議把它分成多行來幫助追蹤錯誤的位置。 –

+0

這是一個編譯器錯誤,對嗎?如果你甚至不能編譯程序,那麼問題出在語法上,而不是內存分配上。 –

+0

你沒有顯示'placeExists'的作用,但是在它的表面上,你沒有檢查到'matrix.find(source) - > second-> find(dest)'成功嘗試解引用它。 –

回答

1

哪裏出問題了就是在你的addPlace()函數裏面。 您的代碼:

Road *road = new Road(); 
unordered_map<string, Road*> *newRelationship = new unordered_map<string, Road*>; 
newRelationship->insert({ {place},{road} }); 

// add to network 
matrix.insert({ { place },{ newRelationship } }); 

創建一個新的道路,能夠代表自己從城市的鏈接,而不是任何其他人。例如,您的來電

road_network->addPlace("Sacremento"); 

後您的matrix樣子:

  • 「薩克拉門託」
    • 「薩克拉門託」:<路>

而且AFTE [R您的來電

road_network->addPlace("Antelope"); 

它看起來像:

  • 「薩克拉門託」
    • 「薩克拉門託」:<路>
  • 「羚羊」
    • 「羚羊」:<路>

所以,以後當你嘗試做road_network->connectPlace("Sacremento", "Antelope", 5);它正在尋找與鍵「羚羊」在unordered_map關鍵「薩克拉門託」下的matrix條目地圖,它不存在。因此,當您嘗試取消引用由matrix.find(source)->second->find(dest)創建的迭代器並訪問它的second成員時,它會拋出錯誤,因爲迭代器無效。

有兩種方法可以解決這個問題:

  1. addPlace被調用時,添加到newRelationship條目在matrix每個現有的地方,並添加到每個現有的地方在unordered_map的條目matrix爲新的地方。 (對於存儲和處理來說,這對於大型數據集來說效率相當低,存儲效率低,因爲它必須存儲(多個地方)^ 2個條目,其中許多數據可能未被使用,處理效率低,因爲每次新地方加入,每一個現有地方必須通過被環)
  2. addPlace只需添加一個空unordered_mapmatrix下鍵place。在connectPlace,如果matrix.find(source)->second->find(dest)返回無效迭代器(由如果返回的值是等於matrix.end()確定),則在matrix與關鍵dest添加下的鍵source一個新條目unordered_map和值與所述給定一個新的道對象重量。
+0

這是正確的答案。當你在(1)中說「低效率」時,你只是暗示空間效率低下,正確,因爲它會是O(| V |^2)? – blueman

+1

@mannerofallthings空間效率低下,處理效率低下。空間效率低下,因爲使用的空間會隨着地點的數量而呈指數增長,並且處理效率低下,因爲每次添加新地點時都會循環訪問每個條目。 – BurningLights

3

問題的一大部分是你試圖在一行代碼中做太多的事情。

if (matrix.find(source)->second->find(dest)->second->connected) 

這應該被分解成幾行。具體來說,您需要確保任何調用find()真正成功,然後再繼續:

auto found = matrix.find(source); 
if (found != matrix.end()) { 
    // keep going 
} 
else { 
    // print error message 
} 

就個人而言,我喜歡這種解決方案比重構你的placeExists()有兩個原因:

  1. 這避免了find()多個呼叫。
  2. 這明確顯示每個數據結構的每個訪問。
  3. 它避免了當matrix中存在密鑰時它也存在於嵌套unordered_map中的假設。
+0

或只使用'auto'。 –

+0

@Galik好點。正如Jonathon Potter指出的那樣,「auto」更清潔。 –