当前位置: 首页 > 知识库问答 >
问题:

可以将一系列键映射到值的数据结构

蒋浩
2023-03-14

我试图找到一种数据结构,它从一系列值中获取特定值并将其映射到键。

例如,我有以下条件:

  1. 从1到2.9,我想把它映射到A.
  2. 从4到6,我要把它映射到B.
  3. 从6.5到10,我想把它映射到C.

我的值为 5,我想将其映射到一个键。所以基于上述条件,我应该将其映射到B。

Java中有什么数据结构可以推荐给我来解决这个问题吗?

目前我正在使用一个只能将值映射到键的哈希表。我尝试将值的范围映射到哈希表中存在的特定值。但是,我陷入了将值范围映射到特定值的映射中。所以现在我正在尝试做另一种将值范围映射到键的方法。有人知道我如何解决这个问题吗?

编辑:

感谢马丁·埃利斯,我决定用TreeMap来解决这个问题。

共有3个答案

壤驷德宇
2023-03-14

HashMap不适用于将范围映射到值,除非您找到一种方法来为范围和其中匹配的单个值生成哈希码。但是下面的方法可能是您正在寻找的

public class RangeMap {
    static class RangeEntry {
        private final double lower;
        private final double upper;
        private final Object value;
        public RangeEntry(double lower, double upper, Object mappedValue) {
            this.lower = lower;
            this.upper = upper;
            this.value = mappedValue;
        }
        public boolean matches(double value) {
            return value >= lower && value <= upper;
        }
        public Object getValue() { return value; }
    }

    private final List<RangeEntry> entries = new ArrayList<RangeEntry>();
    public void put(double lower, double upper, Object mappedValue) {
        entries.add(new RangeEntry(lower, upper, mappedValue));
    }
    public Object getValueFor(double key) {
        for (RangeEntry entry : entries) {
            if (entry.matches(key))
                return entry.getValue();
        }
        return null;
    }
}

你可以的

RangeMap map = new RangeMap();
map.put(1, 2.9, "A");
map.put(4, 6, "B");

map.getValueFor(1.5); // = "A"
map.getValueFor(3.5); // = null

它不是很有效,因为它只是迭代一个列表,如果你在其中放置冲突的范围,它不会在那种状态下抱怨。将只返回它找到的第一个。

P.S.:这样的映射就是将一系列键映射到一个值

郎永福
2023-03-14

Guava RangeMap提供现成的专业解决方案:

RangeMap<Integer, String> rangeMap = TreeRangeMap.create();
rangeMap.put(Range.closed(1, 100), "foo"); // {[1, 100] => "foo"}
rangeMap.put(Range.open(3, 6), "bar"); // {[1, 3] => "foo", (3, 6) => "bar", [6, 100] => "foo"}

rangeMap.get(42); // returns "foo"
连德义
2023-03-14

您的范围不重叠吗?如果是这样,您可以使用树形图:

TreeMap<Double, Character> m = new TreeMap<Double, Character>();
m.put(1.0, 'A');
m.put(2.9, null);
m.put(4.0, 'B');
m.put(6.0, null);
m.put(6.5, 'C');
m.put(10.0, null);

查找逻辑有点复杂,因为您可能需要一个包含性的查找(即2.9映射到‘A’,而不是未定义的):

private static <K, V> V mappedValue(TreeMap<K, V> map, K key) {
    Entry<K, V> e = map.floorEntry(key);
    if (e != null && e.getValue() == null) {
        e = map.lowerEntry(key);
    }
    return e == null ? null : e.getValue();
}

例:

mappedValue(m, 5) == 'B'

更多结果包括:

0.9 null
1.0 A
1.1 A
2.8 A
2.9 A
3.0 null
6.4 null
6.5 C
6.6 C
9.9 C
10.0 C
10.1 null
 类似资料:
  • 问题内容: 我试图找到一种数据结构,该数据结构从一系列值中获取特定值并将其映射到键。 例如,我具有以下条件: 从1到2.9,我想将其映射到A。 从4到6,我想将其映射到B。 从6.5到10,我想将其映射到C。 我的值为5,我想将其映射到键。因此,根据上述条件,我应该将其映射到B。 Java中是否有任何人可以推荐给我解决问题的数据结构? 目前,我正在使用只能将值映射到键的哈希表。我试图将值的范围映射

  • 问题内容: 我正在寻找有关如何在Python中将一个范围值转换为另一范围值的想法。我正在从事硬件项目,正在从可返回一定范围值的传感器读取数据,然后使用该数据来驱动需要不同范围值的执行器。 例如,假设传感器返回的值在1到512的范围内,并且执行器由5到10的值驱动。我想要一个函数,我可以传递一个值和两个范围并取回该值映射到第二个范围。如果这样的函数被命名,则可以这样使用: 在此示例中,我希望输出为,

  • 问题内容: 我有一个数据框 我有另一个数据框df2 我希望我的最终数据框看起来像: 即从一个数据框映射到另一个创建新列 问题答案: + 假设您的数据框已经在上排序,则第一次排序调用是多余的,在这种情况下,您可以删除它。 / 或者,显式创建映射。如果您以后要使用它,它将起作用。

  • 我有一个数据框 我有另一个数据帧df2 我希望我的最终数据帧看起来像: i、 e从一个数据帧映射到另一个数据帧,创建新列

  • 想改进这个问题吗?通过编辑这篇文章添加细节并澄清问题。 我所拥有的是, 我想要的是, 其中,

  • 我有个问题。我在enter中得到了一个csv,其值如下: 该文件的名称类似于:AB01_TEST_ABDC_YYYYMMDd.csv 我需要把它们放到一张地图上,就像: Bar是csv中一行的bean,Foo是由Bar的一些元素创建的bean 现在,我成功地通过CSV的第一列值将列表拆分为一个映射。这给了: 我是这样做的: baz必须被csv的第一列和每个第一列值的行的itération拆分。因为