Search code examples
javaalgorithmdata-structureslookupjava-6

Data Structure for easy look up


I am looking for a data structure / algorithm in java that does the following -

  1. Store the data set into some data structure for easy look up
  2. Choose closest (A value to get B) if an exact match doesn't exist
  3. If exactly in between, choose higher value of A to get B

I have pairs of numbers, for example -

A   B
80  0
76  1
64  3
56  4
48  10

I would only know value of A and should find out / derive the value of B by doing a straight lookup by applying above rules.

Examples - 1

If I get value as 80, output is 0

Example - 2

If I get value as 75, output is 1 [as per rule 2]

Example - 3

If I get value as 70, output is 1 [as per rule 3]

Any advice?

Updates based on Comments - log(N) lookup is acceptable. I am open to implementing it myself but needs suggestions on how to achieve it. Range of A varies between 0 to 1000 with 1 digit precision points.


Solution

  • There's actually already a data structure which does exactly what you're looking for, which is the TreeMap.

    It has methods which allow you to get the 'floor' and 'ceiling' of a key. After that a little math will get you the value you actually want to return:

    public static TreeMap<Integer, Integer> tm = new TreeMap<>();
    
    public static void main(String[] args) throws Exception {
        tm.put(80, 0);
        tm.put(76, 1);
        tm.put(64, 3);
        tm.put(56, 4);
        tm.put(48, 10);
    
        System.out.println(myGet(80));  // 0
        System.out.println(myGet(75));  // 1
        System.out.println(myGet(70));  // 1
    }
    
    public static int myGet(int key) {
        Integer value = tm.get(key);
    
        if (value == null) {
            Entry<Integer, Integer> floor = tm.floorEntry(key);
            Entry<Integer, Integer> ceiling = tm.ceilingEntry(key);
    
            if ((key - floor.getKey()) < (ceiling.getKey() - key)) {
                value = floor.getValue();
            } else {
                value = ceiling.getValue();
            }
        }
    
        return value;
    }
    

    Note: I didn't bother with proper null checking for when there is no floor/ceiling, but you get the idea.