¿Cuál es la estructura de datos java correcta y algoritmo de búsqueda para buscar un conjunto de rangos de IP para su inclusión

Jim:

Dada la siguiente lista si rangos de direcciones IP.

LOW           HIGH
192.168.10.34 192.168.11.200
200.50.1.1    200.50.2.2

Suponiendo que la iteración todas las direcciones dentro de todos los rangos y almacenarlos en un HashSet utilizará demasiada memoria.

Por lo que necesitamos para mantener los rangos, que son en realidad sólo los números cambiaban todos modos (bajo y alto). ¿Cómo se podría almacenar los rangos en un árbol y luego utilizar una búsqueda eficiente para encontrar si es o no una dirección particular está dentro de la gama (s).

He mirado RangeTree , pero parece que buscar puntos en un plano cartesiano, y no parece adecuado para mi caso de uso. KDTree permite buscar vecino más cercano, y cuando k == 2 es básicamente el mismo que el árbol alcance.

Me gustaría que todos los partidos, ya que puede haber múltiples golpes.

Lo que funcionaría aquí? Estoy muy seguro de que esto es un problema resuelto.

Andreas:

Una norma TreeMapva a hacer, suponiendo que tiene no hay intervalos que se solapan.

Basta con crear una TreeMap, cerrado por el extremo inferior de la gama, con la gama completa como el valor. Busque el rango usando floorEntry(K key)y verificar el valor está en el rango.

Ejemplo utilizando sencilla Integeren lugar de IpAddressobjeto, pero cualquier Comparableobjeto puede ser utilizado como límites de rango.

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 + ")";
    }
}

Prueba

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));

Salida

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

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=279717&siteId=1
Recomendado
Clasificación