Reputation: 1218
Basically I have a 2xN array of ints to ints, which indicates from which position to which position of an objects location. Then I have a second array of ints and I want to find which ints land on which object. So for example:
First array
A: 0 - 500
B: 501 - 900
C: 901 - 1055
D: 1056 - 9955 etc.
Second array: 1, 999, 3, 898, 55, 43, 1055, 593, 525, 3099, etc.
This should return the A, C, A, B, A, A, C, B, B, D, etc.
What I am trying to figure out is if there is a way to hash the first array, using some hash functions, such that when hashing the second array I will get a collision if it falls within the range of an object. Any ideas how to do this or if its possible?
Thanks!
Upvotes: 14
Views: 11541
Reputation: 5013
You can use a NavigableMap
.
Example Code:
NavigableMap<Integer, String> map = new TreeMap<Integer, String>();
map.put(0, "A");
map.put(501, "B");
map.put(901, "C");
map.put(1056, "D");
System.out.println(map.floorEntry(1).getValue());
System.out.println(map.floorEntry(999).getValue());
System.out.println(map.floorEntry(3).getValue());
System.out.println(map.floorEntry(898).getValue());
Output:
A C A B
Upvotes: 7
Reputation: 86
You can use some data structure like an interval tree to store the first array.
http://en.wikipedia.org/wiki/Interval_tree
Then when you go through the second array, you can simply query the tree for a matching interval. This way, you will require O(log n) time to query each element of the second array.
Upvotes: 3
Reputation: 13948
You problem seems closely related to BWT decoding.
If i do understand your problem correctly, you receive the first array as a stream.
Then, if you have the second array in memory, you simply need to build the "reverse array" of it. So that, for example :
Second array: 1, 9, 3, 8, 5, 4, 2, 6, 7
Becomes
Inverse second array : 1, 7, 3, 6, 5, 8, 9, 4, 2
So, now, on receiving your stream, you know immediately where to place each character.
Upvotes: 0
Reputation:
You can't use hashing, but you can sort the interval end-points and do a bisection search.
Something like this (in python, but hopefully it makes sense to you):
endpoints = [501, 901, 1056, 9956]
for x in [1, 999, 898, 55, 43, 1055, 593, 525, 3099]:
print x, 'ABCD'[bisect.bisect_left(endpoints, x)]
Upvotes: 1