【问题标题】:Dynamic programming in java (memoizing multiple key parameters)java中的动态编程(记住多个关键参数)
【发布时间】:2016-01-10 06:36:20
【问题描述】:

我在java中做动态编程,我遇到了这个问题,函数接受三个参数,其中两个是整数,第三个是整数数组。我知道缓存 1 或 2 参数函数的值可以使用 1d/2d 数组来实现。我正在考虑可能正在使用 HashMap,但我正在尝试寻找一种更好的方法将这三个索引捆绑在一起作为 hashmap 的键

【问题讨论】:

  • 创建一个可以包含这 3 个值的 Key 类?

标签: java hashtable dynamic-programming


【解决方案1】:

创建一个包含所有参数的新类并将其添加到地图中。
确保同时实现hashCode() & equals()

class MemoKey {
    Integer a;
    Integer b;
    Integer[] array;

    public MemoKey(Integer a,Integer b, Integer[] array) {
        this.a = a;
        this.b = b;
        this.array = array;
    }

    @Override
    public int hashCode() { 
        // implement 
    }

    @Override
    public boolean equals(Object obj) {
        // implement
    }
}

然后把这个类和你的结果对象放在地图中。

HashMap map = new HashMap<MemoKey, Object>();

Object result = map.get(memoKey);
if (result == null)
    map.put(memoKey, calcResult());

【讨论】:

    【解决方案2】:

    这是一个使用 Apache Commons Collections 的示例:

    public static void main(String[] args) {
    
        MultiKeyMap multiKeyMap = new MultiKeyMap();
    
        int[] array1 = new int[10];
        int[] array2 = new int[10];
    
        multiKeyMap.put(13,52,array1, "First");
        multiKeyMap.put(81,22,array2, "Second");
    
        System.out.println(multiKeyMap.get(81,22,array2));  
    }
    

    【讨论】:

    • 是的,这就是它的美妙之处。你可以随心所欲地做钥匙
    • 在您的代码中,multiKeyMap.get(81,22,array1) 返回 null。 array1array2 具有相同的值但不同的哈希码值。
    • 当然返回null;这两个数组是两个不同的对象。
    【解决方案3】:

    创建不可变类,接受两个泛型和一个整数数组作为常量类型(如果您知道将使用其他数字类型,可以将其更改为):

    public final class CustomKey<F,S> {
    private final F firstValue;
    private final S secondValue;
    private final int[] thirdValue;
    
    public CustomKey(final F firstValue,
                     final S secondValue,
                     final Integer[] thirdValue){
        this.firstValue = firstValue;
        this.secondValue = secondValue;
        this.thirdValue = unboxingArray(thirdValue);
    }
    
    public S getSecondValue() {
        return secondValue;
    }
    
    
    public F getFirstValue() {
        return firstValue;
    }
    
    public int[] getThirdValue() {
        return thirdValue;
    }
    
    private static int[] unboxingArray(final Integer[] array){
        final int[] result = new int[array.length];
        IntStream.range(0,array.length)
                .forEach(index -> result[index] =  array[index]);
        return result;
    }
    
    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
    
        final CustomKey<?, ?> customKey = (CustomKey<?, ?>) o;
        return getFirstValue().equals(customKey.getFirstValue()) 
                && getSecondValue().equals(customKey.getSecondValue()) 
                && Arrays.equals(getThirdValue(), customKey.getThirdValue());
    
    }
    
    @Override
    public int hashCode() {
        int result = getFirstValue().hashCode();
        result = 31 * result + getSecondValue().hashCode();
        result = 31 * result + Arrays.hashCode(getThirdValue());
        return result;
    }
    

    }

    如果您希望能够比较数组中的整数,则需要对整数数组进行拆箱。如果要实现其他类型,请在拆箱前进行 instanceOf 检查。

    然后,像使用任何其他键一样加载您的地图:

    public static void main(String[]args){
        //Assume your Value is a String which does not really matter
        Map<CustomKey<Integer,Integer>,String> customKeyMap =
                new HashMap<>();
        customKeyMap.put(new CustomKey<>(1,2,new Integer[]{1,2,3}),"First Value");
        customKeyMap.put(new CustomKey<>(1,3,new Integer[]{1,2,3}),"Second Value");
    
        //Can use anonymous instance since equals is implemented
        //Expect Second Value
        System.out.println(customKeyMap.get(new CustomKey<>(1,3,new Integer[]{1,2,3})));
    }
    

    【讨论】:

      猜你喜欢
      • 2018-08-02
      • 2014-02-19
      • 2014-07-30
      • 2013-04-10
      • 2011-04-20
      • 2012-12-02
      • 2021-03-24
      • 2023-03-05
      • 1970-01-01
      相关资源
      最近更新 更多