2

2 つのキーに基づいてルックアップ テーブルを作成する必要があります。道路地図の裏にあるものと同様のマイレージ ルックアップ チャートを作成しています。チャートのサンプルはこちらにあります。開始都市が x で終了都市が y であることがわかっている場合は、交差点を探して合計マイルを調べます。

私が最初にこの問題に取り組み始めたとき、私は 2 つのマップを考えていました。City は、関心のある都市の ENUM です。

Map<City, Map<City, Integer>> map;

しかし、調査したところ、Map 型の値を持つ Map に関する警告が表示されています。私が見落としているかもしれない私の問題に対するより簡単な解決策はありますか? これは 66x66 の列 * 行であるため、データ入力をやり直す必要がなく、最初に正しく行う必要があります。

注として、簡単に更新および取得できるようにすべての値をデータベースに保存するので、ソリューションは JPA や Hibernate などで簡単にマップできる必要があります。

ありがとうございます。

4

7 に答える 7

6

これを行うと簡単になります:

Map<Pair<City, City>, Integer> map;

つまり、新しいジェネリック クラスを作成し、それPairを都市のペアを表すと呼び、それを のキーとして使用しますMap。もちろん、オーバーライドhashCode()equals()inを忘れないでくださいPair。@increment1 の回答を見てください。彼は正しいです。都市 A から B までの距離が B から A までの距離と同じである場合、都市の 2 つのペアを保存する必要はなく、1 つのペアで十分です。に都市を追加するために使用される順序Map

これは、データベースで複合キーをマッピングするときに ORM (JPA など) で使用される戦略であることに注意してください。Pairキーとして使用されるすべてのオブジェクトをカプセル化する新しいクラス (例では) を作成すると、これを管理するのがはるかに簡単になります。方法: 概念的には、キーは 1 つだけです。たとえ内部的にそのキーが複数の要素で構成されていたとしてもです。

于 2013-08-12T19:56:10.933 に答える
3

Path のマップを作成します。ここで、Path は 2 つの都市を保持するカスタム クラスです。equals と hashcode をオーバーライドすることを忘れないでください。

編集: 66x66 パスがあるのはなぜですか? 行き方によって走行距離は違うのですか?そうでない場合は、その数のエントリの半分以上を破棄できます (半分は明白です。「より多く」の部分は New York から New York へのエントリです。エントリを 0 で保存する必要はありません)。

于 2013-08-12T19:55:50.053 に答える
2

および を適切にオーバーライドするとおよびの 2 つのCity参照を含む単純なクラスを作成する必要があります。次に、それをキーとして使用します。fromtoequalshashCode

于 2013-08-12T19:55:50.820 に答える
2

他の回答と同様に、マップのキーとなる都市ペア クラスを作成することをお勧めします (したがって、マップのマップは避けてください)。ただし、私が行う 1 つの違いは、hashCodeメソッドequals内の都市に関して、都市のペア クラスの順序を不可知なものにすることです。

すなわちCityPair(Seattle,LA)に等しくしCityPair(LA,Seattle)ます。

これの利点は、マップ内の不要なエントリが自動的に複製されないことです。

これを実現するには、列挙型の中で( 経由で ) より低い序数の値を持つ都市を city1 と見なしhashCode、常に考慮します。equalsEnum.ordinal()

または、別の質問と回答で示されているこの単純な順序付けられていないペアの実装を試してください。

于 2013-08-12T20:16:56.333 に答える
1

Eclipse Collectionsを使用している場合は、MutableObjectIntMapとを使用できますPair

MutableObjectIntMap<Pair<City, City>> map = ObjectIntHashMap.newMap();
map.put(Tuples.pair(newYorkCity, newark), 10);
map.put(Tuples.pair(newYorkCity, orlando), 1075);
Assert.assertEquals(10, map.get(Tuples.pair(newYorkCity, newark)));
Assert.assertEquals(1075, map.get(Tuples.pair(newYorkCity, orlando)));

Pairフレームワークに組み込まれているため、独自に作成する必要はありません。MutableObjectIntMapに似てMap<Object, Integer>いますが、メモリ用に最適化されています。これは Object 配列と int 配列に支えられているため、Integerラッパー オブジェクトの格納を回避します。

注:私は Eclipse コレクションのコミッターです。

于 2013-08-12T20:58:40.790 に答える
0

グラフィックと同じことを行うには、2次元配列を使用します。

// index is the city code:
int[][] distances;

都市コードを

 Map<String, Integer> cityNameToCodeMap

次のように使用します。

Integer posA = cityNameTCodeMap.get("New York");
// TODO check posA and posB for null, if city does not exits
Integer posB = cityNameTCodeMap.get("Los Angeles");

int distance = distances[posA][posB];

この設計の理由:
グラフィック内のマトリックスはスパース マトリックスではなく、完全なマトリックスです。その場合、2 次元配列は最小のメモリを使用します。

于 2013-08-12T19:57:59.783 に答える