ジム:
IPアドレスの範囲ならば、次のリストを考えます。
LOW HIGH
192.168.10.34 192.168.11.200
200.50.1.1 200.50.2.2
HashSetの中ですべての範囲内のすべてのアドレスを反復処理し、それらを格納すると、あまりにも多くのメモリを使用すると仮定すると。
私たちは実際にとにかく数字をシフトされた範囲、(低・高)を維持する必要がありますので。どのようにして、ツリー内の範囲を格納し、特定のアドレス範囲(複数可)内にあるか否かを見つけるために、効率的な検索を使用します。
私が見てきましたRangeTreeが、デカルト平面上の点を探しているようだ、と私のユースケースに適していないようです。KDTreeは、 1が最も近い隣人を検索することができ、そしてときのk == 2には、基本的にはレンジツリーと同じです。
複数のヒットがあるかもしれないように私は、すべての一致を望みます。
ここで何を働くだろうか?私は非常に必ず、これが解決される問題であると思います。
アンドレアス:
標準では、TreeMap
あなたが何の重複範囲を持っていないと仮定して、行います。
単に作成するTreeMap
値として全範囲で、範囲の下端をキー、。使用範囲を検索floorEntry(K key)
し、値が範囲内にあることを確認します。
例えば、単純な使用Integer
の代わりにIpAddress
オブジェクトを、任意Comparable
のオブジェクトは、範囲の境界として使用することができます。
public final class RangeMap<T extends Comparable<T>> {
private TreeMap<T, Range<T>> map = new TreeMap<>();
public void add(Range<T> range) {
Entry<T, Range<T>> entry = this.map.floorEntry(range.getUpperInclusive());
if (entry != null && entry.getValue().overlaps(range))
throw new IllegalArgumentException("Overlap: " + range + " vs " + entry.getValue());
entry = this.map.ceilingEntry(range.getLowerInclusive());
if (entry != null && entry.getValue().overlaps(range))
throw new IllegalArgumentException("Overlap: " + range + " vs " + entry.getValue());
this.map.put(range.getLowerInclusive(), range);
}
public boolean contains(T value) {
Entry<T, Range<T>> entry = this.map.floorEntry(value);
return (entry != null && entry.getValue().contains(value));
}
public Range<T> get(T value) {
Entry<T, Range<T>> entry = this.map.floorEntry(value);
return (entry != null && entry.getValue().contains(value) ? entry.getValue() : null);
}
}
public final class Range<T extends Comparable<T>> {
private final T lowerInclusive;
private final T upperInclusive;
public Range(T lowerInclusive, T upperInclusive) {
this.lowerInclusive = lowerInclusive;
this.upperInclusive = upperInclusive;
}
public T getLowerInclusive() {
return this.lowerInclusive;
}
public T getUpperInclusive() {
return this.upperInclusive;
}
public boolean contains(T value) {
return (value.compareTo(this.lowerInclusive) >= 0 &&
value.compareTo(this.upperInclusive) <= 0);
}
public boolean overlaps(Range<T> that) {
return (this.lowerInclusive.compareTo(that.upperInclusive) <= 0 &&
this.upperInclusive.compareTo(that.lowerInclusive) >= 0);
}
@Override
public String toString() {
return "(" + this.lowerInclusive + "-" + this.upperInclusive + ")";
}
}
テスト
RangeMap<Integer> map = new RangeMap<>();
map.add(new Range<>(50, 59));
map.add(new Range<>(70, 79));
for (int i = 40; i <= 90; i += 3)
System.out.println(i + ": " + map.contains(i));
出力
40: false
43: false
46: false
49: false
52: true
55: true
58: true
61: false
64: false
67: false
70: true
73: true
76: true
79: true
82: false
85: false
88: false