-1

由于我需要获取我正在使用的双精度值的键值BiMap

BiMap<String,Double>mapObj = HashBiMap.create();
mapObj.put("a1",3.58654);
mapObj.put("a2",4.1567);
mapObj.put("a3",4.2546);

对于像 4.0156 这样的特定值,我必须得到键值 a2.. 也就是说,如果,

Double value=4.0156; 
mapObj.inverse().get(value)=a2 

我尝试了很多方法,但它总是为空,因为没有完全匹配。请任何人帮助我...如果我选择了错误的方式,请更正它,因为我是 Java 新手。

4

4 回答 4

1

第一:你可能想要:

Map<String, Double> mapObj = HashMap<>();
mapObj.put("a1", 3.58654);
mapObj.put("a2", 4.1567);
mapObj.put("a3", 4.2546);
mapObj.put("a4", 4.1567); // Repeated value

然后你想要一个具有最接近值的反向查找。

为此,最好将所有条目按值排序。这不能是 Set,因为一个值多次出现。

List<Map.Entry<String, Double>> entries = new ArrayList<>(mapObj.entrySet());
Comparator<Map.Entry<String, Double>> cmp = (lhs, rhs) ->
    Double.compare(lhs.getValue(), rhs.getValue());
Collections.sort(entries, cmp);

我知道 Java 中没有结合此的数据结构。虽然可能有。为了不丢失信息,我使用 Map.Entry 键值对。这需要一个比较器的值。简而言之,我在这里借鉴了 Java 8 语法。

现在搜索:

Map.Entry<String, Double> nearest(double value) {
    int index = Collections.binarySearch(entries, cmp);
    if (index < 0) { // Not found
        index = -index + 1; // The insertion position
        Map.Entry<String, Double> before = index != 0 ? entries.get(i - 1) : null;
        Map.Entry<String, Double> after = index < entries.size() ?
                entries.get(i) : null;
        if (before == null && after == null) {
            return null;
        } else if (before == null) {
            return after;
        } else if (after == null) {
            return before;
        }
        return value - before.getValue() < after.getValue() - value ? before : after;
    }
    return entries.get(index);
}

要在 delta 中查找值的子列表,需要使用索引。

现在每次搜索都花费 ²log N,这是可以接受的。

于 2014-11-19T14:18:38.673 回答
0

转换为键和值倒置的排序映射并应用以下方法应该可以工作。

 private static Double getClosest(TreeMap<Double, String> mySet, Double d) {
        if (mySet.ceilingKey(d) != null && mySet.floorKey(d) != null){
            if( Math.abs(d - mySet.ceilingKey(d)) < Math.abs(d - mySet.floorKey(d)) )
                return mySet.ceilingKey(d);
            else
                return mySet.floorKey(d);
        }
        else if (mySet.ceilingKey(d) == null && mySet.floorKey(d) != null) {
            return mySet.floorKey(d);
        } else if (mySet.ceilingKey(d) != null && mySet.floorKey(d) == null) {
            return mySet.ceilingKey(d);
        } else
            return null;
    }
于 2014-11-19T14:12:33.560 回答
0

像这样遍历一个条目集应该可以解决问题。

String nearestKey = null;
Double nearestValue = null;
for(Entry<String,Double> e : map.entrySet()){
    //if e.getValue() is nearer than prev nearestValue
    // nearestKey = e.getKey();
    // nearestValue = e.getValue();
}

您只需要编写一个函数来确定键是否比前一个更接近并更新变量。

于 2014-11-19T13:56:32.240 回答
0

您将必须遍历所有键值对并选择与您正在寻找的值最接近的值。

public String searchClosest(Map<String,Double> map, double value)
{
    double minDistance = Double.MAX_VALUE;
    String bestString = null;

    for (Map.Entry<String,Double> entry : map.entrySet()) {
        double distance = Math.abs(entry.getValue() - value);
        if (distance < minDistance) {
            minDistance = distance;
            bestString = entry.getKey();
        }
    }

    return bestString;
}
于 2014-11-19T13:58:39.267 回答