私は文字列のリストを持っています。double を返す関数に基づいて各文字列を評価したいと考えています。次に、計算された値に基づいて、最初の 5 つの文字列が必要です。5つに満たない場合は、すべて(順番に)欲しいです。文字列が化学化合物であり、関数が質量を計算するとしましょう。関数は計算コストが高くなります。文字列ごとに 1 回評価する必要があります。(ただし、ここではデータを作成しているだけです。)
H2O => 18.5
C12H11O22 => 109.1
HeNe => 32.0
H2SO4 => 54.37
HCl => 19.11
4FeO3 => 82.39
Xe6 => 281.9
プログラムは、それぞれの値の順に並べられた最初の 5 つの文字列を返す必要があります。このサンプル データの場合: H20, HCl, HeNe, H2SO4, 4FeO3
. 実際、順番はあまり気にしません。必要なのは、任意の順序で最も低い 5 つだけです。
Perl でこれを行う方法を考えました。それはほんの数行です:
foreach $s (@str) {
$strmap{$s} = f($s);
}
@sorted = sort { $strmap{$a} <=> $strmap{$b} } keys %strmap;
return @sorted[0, 4]
しかし、私はJavaでそれを行う必要があります。そして、それは私を夢中にさせています。
まず、Perl バージョンと同じように、カスタム コンパレータHashMap<String, Double>
を使用して、 を設定してみました。Collections.sort
しかし、Comparator のスコープにより、HashMap を参照して値を検索することができませんでした。
次に、を試しましたTreeMap<String, Double>
が、キーでソートするだけで、強制的にエントリを値で並べ替えることができませんでした。
だから私は試してみましたTreeMap<Double, String>
。同じ Double を持つエントリは破棄されます。ただし、同じ Double にマップされる String を持つ可能性は低いため、先に進みました。TreeMap にエントリを追加することは問題ありませんが、そこから値を抽出しようとすると問題が発生しました。
TreeMap は と呼ばれるメソッドを提供subMap
しますが、そのパラメーターはサブセットを区切るキーです。それらが何であるかはわかりません。欲しいのは最初の5つだけです。そこで、このvalues
メソッドを使用して TreeMap からすべての値を取得しようとしました。その後、最初の 10 を取得できます。
ArrayList<String> strs = (ArrayList<String>)(treemap.values());
return new ArrayList<String>(strs.subList(0, 5));
いいえ。実行時エラー: TreeMap$Values を ArrayList にキャストできません。
List<String> strs = (List<String>)(treemap.values());
return new ArrayList<String>(strs.subList(0, 5));
同じ。キャストを実行しようとしたときにランタイム エラーが発生しました。OK、コレクションに割り当てましょう...
Collection<String> strs = treemap.values();
return new ArrayList<String>(strs.subList(0, 5));
申し訳ありませんが、subList
コレクションの方法ではありません。
Collection<String> strs = treemap.values();
ArrayList<String> a = new ArrayList<String>(strs);
return new ArrayList<String>(a.subList(0, 5));
最後に、機能するもの!しかし、最初の 5 つの要素を取得するためだけに 2 つの追加のデータ構造が必要ですか? また、私は Double を TreeMap のキーとして使用することについて、それほど熱心ではありません。
より良い解決策はありますか?