どのような正しいJavaデータ構造であり、包含のためにIP範囲のセットを検索するためのアルゴリズムを検索

ジム:

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

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=279714&siteId=1