2012-02-01 15 views
12

¿Hay alguna razón en particular por la cual faltan estos?¿Por qué Java `BitSet` no tiene las funciones` shiftLeft` y `shiftRight`?

Existen en BigInteger, pero debido al patrón de diseño inmutable de BigInteger, estos son muy lentos. BitSet es mucho mejor porque es mutable, pero echo de menos las funciones shift (<< y >>> para long s). Para BitSet, un cambio en el lugar también sería útil, así como la rotación cíclica.

He visto la respuesta a Shifting a Java BitSet (usando get(off, len) para cambiar, sin embargo esto requiere copiar).

No me malinterprete. Sé dónde reportar errores. Me pregunto si hubo un motivo en particular para omitirlos, p. algún patrón de diseño o tal concepto. En particular, ya que son incluidos en BigInteger.

+0

Porque es un 'conjunto', no una 'cadena'. – bmargulies

+1

@bmargulies: Un 'long' tampoco es una cadena. Sin embargo, tiene operadores de turno. Y un 'String' en realidad no tiene. Y la semántica 'get (i, j)' esencialmente concuerda con 'substring', y tampoco están disponibles para' long' ... –

+0

El término 'set' significa 'an * desordered * collection'. El BitSet tiene la función de saber qué potencias de 2 están encendidas, no de mezclarlas. – bmargulies

Respuesta

9

Conceptualmente, un BitSet es generalmente/a menudo utilizado para rastrear una gran cantidad de configuraciones, de modo que cada bit en el conjunto tiene un significado específico. Entonces, una operación de cambio tiene poco sentido en ese contexto.

Ha encontrado claramente otro propósito útil para un BitSet, pero está fuera del alcance para el cual BitSet fue probablemente previsto.

+1

Para citar de [los documentos] (http://docs.oracle.com/javase/6/docs/api/java/util/BitSet.html): BitSet se visualizó como _ "un vector de bits que crece según sea necesario" " Esto es mucho más general que el uso típico que sugieres. Otras clases vectoriales (Vector, ArrayList, etc.) no tienen una operación de "cambio", pero sí tienen operaciones de "inserción" y "eliminación" que efectivamente hacen lo mismo. Tendría sentido para BitSet tener una funcionalidad similar, pero no es así. –

+0

El punto de 'ajuste' (no ordenado) es bueno, excepto que se usa de manera poco habitual. Gracias. –

+0

Me cuestiono la opinión de que BitSet es para la configuración. Si estoy haciendo ajustes, o uso bits en int/long, al igual que "programadores reales" :-) hace 20 años, o, más correctamente, usaré Enums y un EnumSet. Tiendo a usar BitSets más como un conjunto '' escaso/compacto. – user949300

1

Supongo que haría que algunos de sus códigos fueran más complicados. Por ejemplo, si "dejaste cambiar por 3" todo, podrías tener un campo adicional, shift, que es -3 (o tal vez 3, solo tengo un 50% de probabilidad de hacerlo bien :-). Y, para los métodos get() y set(), si simplemente ajusta bitIndex por turno, el código debería funcionar. p.ej.

public boolean get(int bitIndex) { 
    bitIndex += shift; // new code!!! 
    if (bitIndex < 0) 
     throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex); 

    checkInvariants(); 

    int wordIndex = wordIndex(bitIndex); 
    return (wordIndex < wordsInUse) 
     && ((words[wordIndex] & (1L << bitIndex)) != 0); 
    } 

Sin embargo, para algunas de las otras operaciones, como se cruza() y o(), el código podría empezar a recibir muy sucia. En este momento el núcleo del método o() es muy simple y rápido:

// Perform logical OR on words in common 
    for (int i = 0; i < wordsInCommon; i++) 
     words[i] |= set.words[i]; 

    // Copy any remaining words 
    if (wordsInCommon < set.wordsInUse) 
    System.arraycopy(set.words, wordsInCommon, 
        words, wordsInCommon, 
       wordsInUse - wordsInCommon); 

Si ambos tenían BitSets posibles desplazamientos esto sería causar problemas rápidamente. Probablemente pensaron que si realmente desea cambiar, debería usar get y copy.

Una cosa que me sorprendió - en get(), no hacen 1L << bitIndex&31. Aparentemente < < gira alrededor, lo cual, ahora que recuerdo mi lenguaje de máquina distante, tiene sentido.

+1

Sí, consideré hacer eso. Pero realmente necesitaba 'o' y' xor' para funcionar. Java realmente tiene código para hacer cambios en 'int []' en 'BigInteger', y podrían copiarlo a' BitSet' para 'long []'. No es realmente muy diferente. –

Cuestiones relacionadas