如果我理解正确,我认为您想要执行城市地图的深层复制,并且正在寻找一种可以有效确保新对象之间的关系与旧对象之间的关系相同的方法。
我同意想法 2,在道路上有一个额外的成员来表示从旧到新的映射,这是可怕的。但是我看不出想法 1 有什么问题,使用 amap
来表示从原始道路到新道路的映射,尽管我认为您还需要从旧城市到新城市以及从旧道路到新道路的映射. 如果你有map
,它只是一张临时地图,只在你的copy
方法中需要,你在新城市地图上的操作可能比复制花费更多的时间。此外,amap
是一个库类,因此将得到很好的优化。如果您使用 C++11(或可以访问 boost),则可以使用形状为 的哈希映射,unordered_map
它为您提供平均 O(1) 而不是对数查找。这种方法给出:
using std::vector;
using std::unordered_map;
class road;
class city;
class cityMap
{
public:
vector<road *> allRoads; // all raods in the area
vector<city *> cities; // all the cities in the area
cityMap *copy() // makes a copy of the entire map
{
cityMap* pNewCityMap = new cityMap;
// create new cities, building up old city to new city map
unordered_map<city*, city*> city2city;
for(city* pOldCity: cities) {
city* pNewCity = new city(*pOldCity);
pNewCityMap->cities.push_back(pNewCity);
city2city[pOldCity] = pNewCity;
}
// create new roads, building up old road to new road map
unordered_map<road*, road*> road2road;
for(road* pOldRoad: allRoads) {
road* pNewRoad = new road(city2city[pOldRoad->from], city2city[pOldRoad->to]);
pNewCityMap->allRoads.push_back(pNewRoad);
road2road[pOldRoad] = pNewRoad;
}
// fix up roads in new cities
for(city* pNewCity: pNewCityMap->cities) {
for(road*& pNewRoad: pNewCity->roads) {
pNewRoad = road2road[pNewRoad];
}
}
return pNewCityMap;
}
};
class road
{
public:
city *from, *to;
road(city* _from, city* _to) : from(_from), to(_to) {}
};
class city
{
public:
vector<road *> roads; // roads from this city to another city
};
另一种方法是受 celtschk 的评论启发,使用索引来表示道路。在这种情况下,城市地图仍然可以返回一个road
类,但必须根据索引在内部存储其道路。下面是一个草图实现。
using std::pair;
typedef size_t roadnum;
class city2
{
public:
vector<roadnum> roads; // roads from this city to another city
};
class road2
{
public:
city2 *from, *to;
road2(city2* _from, city2* _to) : from(_from), to(_to) {}
};
class cityMap2
{
vector<pair<size_t, size_t>> allRoads; // all raods in the area, pairs of city indices
public:
vector<city2 *> cities; // all the cities in the area
cityMap2 *copy(); // makes a copy of the entire map
size_t GetNumberRoads() const { return allRoads.size(); }
road2 GetRoad(size_t which) const
{
const pair<size_t, size_t>& citycity = allRoads[which];
return road2(cities[citycity.first], cities[citycity.second]);
}
};