3

Request タイプの Keys オブジェクトと Integer タイプの Values を持つ Hash Map があります。次のコードを使用して、マップを反復処理し、すべての最小値を取得してから、それらのキーをリストに追加します。キーは一意ですが、値は重複する可能性があるため、すべてを強調します。したがって、最小値を持つ複数のマップ要素が存在する可能性があります。

ただし、このコードでは、そのような要素は 1 つしか得られません。つまり、反復によって最初に見つかった要素です。他にもあることがわかっているにもかかわらずです。たとえば、マップに次のリクエストがあるとします。つまり、キーです (リクエスト ID を指定します)。5 | 2 で、それぞれの値は次のとおりです。4 | 4. したがって、この例では 2 つの最小要素があります。つまり、最小値 ID 5 と ID 2 を共有する 2 つの要素で、どちらも値 4 です。コードは、ID 5 の要素のみをリストに追加します。それらの最初のものです。

同様のスレッド ( Key for maximum value in Hashtable ) があることに注意する必要がありますが、提供されたソリューションは私の場合は機能しません。

コードは次のとおりです。

 Entry<Request, Integer> min = null;

 List<Request> minKeyList = new ArrayList<Request>();

 for(Entry<Request, Integer> entry : this.map.entrySet()) {

      if (min == null || min.getValue() > map.getValue()) {

           min = entry;
           minKeyList.add(entry.getKey());

      }

なぜこれが起こっているのかについての提案や説明をいただければ幸いです。

編集: 新しいアプローチ

さて、私は解決策を見つけました。エレガントではありませんが、機能します。これがコードです。

    // list for finding the min value
    List<Integer> minValList = new ArrayList<Integer>();

    // List for keeping the keys of the elements with the min value
    List<Request> minKeyList = new ArrayList<Request>();

    // scan the map and put the values to the value list
    for(Entry<Request, Integer> entry : this.map.entrySet()) {

        minValList.add(entry.getValue());

    }

    // scan the map   
    for(Entry<Request, Integer> entry: this.map.entrySet()) {

        // find the min value
        if(entry.getValue() == Collections.min(minValList)) {

            // add the keys of the elements with the min value at the keyList
            minKeyList.add(entry.getKey());

       }

    }
4

3 に答える 3

1

2 つのリスト/セットを使用することで、複数のループを回避できます。

ループ開始前

    Set setExisting = new HashSet();
    Map keyMap = new HashMap();
    // find minimum first
    int min = Integer.MIN_VALUE;`enter code here`
    for(Entry<Request, Integer> entry : this.map.entrySet()) {
    Set newSet= new HashSet<String>();
        min = Math.min(min, map.getValue());
        newSet.add(map.getValue(min));
        keyMap.put(min,newSet);
        if (min==map.getValue()){
           setExisting = (Set) keyMap.get(newSet);
           setExisting.add(map.getValue(min));
           keyMap.put(min,setExisting);
         }
  }

  // We will NOT need the below loop in that case
  // add all elements that have a value equal to min
  List<Request> minKeyList = new ArrayList<Request>();
  for(Entry<Request, Integer> entry : this.map.entrySet()) {
    if(min.getValue() == min) {
        minKeyList.add(entry.getKey());
    }
}
于 2016-05-04T14:24:50.617 に答える
1

Matthias Meid が言ったように、 a の>=代わりに aを使用する必要があり>ます。

また、このようなものが必要だと思う場合、または minKeyList にはすべての値が含まれますmin

if(min == null || min.getValue() >= map.getValue()) {
    if(min == null || min.getValue() > map.getValue()){
        min = entry;
        minKeyList.clear();
    }
    minKeyList.add(entry.getKey());
}

編集:テスト済みコード

このメソッドをいくつかのサンプル コードでテストしたところ、正しく動作するようです。

テストに使用したコードは次のとおりです。

public static void main(String[] args) {

    HashMap<Integer, Integer> map = new HashMap<>();
    map.put(7, 12);
    map.put(3, 3);
    map.put(1, 10);
    map.put(4, 12);
    map.put(6, 3);
    map.put(8, 3);
    map.put(9, 13);
    Entry<Integer, Integer> min = null;
    List<Integer> minKeyList = new ArrayList<Integer>();

    for(Entry<Integer, Integer> entry : map.entrySet()) {

        if (min == null || min.getValue() >= entry.getValue()) {
            if(min == null || min.getValue() > entry.getValue()){
                min = entry;
                minKeyList.clear();
            }
            minKeyList.add(entry.getKey());
        }
    }

    for (Integer integer : minKeyList) {
        System.out.println(integer);
    }
}

テストを簡単にするために、キーと値はどちらも整数ですが、何も変更しないでください。

いいえ、ここに私の出力があります:

3
6
8

それは私には正しいようです。これで問題が解決しない場合は、もう少しコードを投稿してみてください。

于 2013-04-18T09:48:21.367 に答える