私の理解が正しければ、都市マップのディープ コピーを実行したいと考えており、新しいオブジェクト間の関係が古いオブジェクト間の関係と同じであることを効率的に確認できる方法を探していると思います。
古いものから新しいものへのマッピングを表すために、道路に追加のメンバーを持つアイデア 2 は恐ろしいことに同意します。map
ただし、古い道路から新しい道路へのマッピングだけでなく、古い都市から新しい都市へのマッピングも必要になると思いますが、 a を使用して元の道路から新しい道路へのマッピングを表すアイデア 1 には多くの間違いはありません。 . を持っている場合map
、それは一時的なマップであり、メソッド中にのみ必要でcopy
あり、新しい都市マップでの操作はおそらくコピーよりも時間がかかります. さらに、 amap
はライブラリ クラスであるため、かなり最適化されます。C++11 を使用している (またはブーストにアクセスできる) 場合は、ハッシュ マップを の形で使用できます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]);
}
};