2010-03-13 10 views
7

Por lo tanto, en Java, siempre que se da un rango indexado, el límite superior es casi siempre exclusivo.¿Se supone siempre que los límites superiores de los rangos indexados son exclusivos?

De java.lang.String:

substring(int beginIndex, int endIndex)

devuelve una nueva cadena que es una subcadena de esta cadena. La subcadena comienza en el beginIndex especificado y se extiende hasta el carácter del índice endIndex - 1

De java.util.Arrays:

copyOfRange(T[] original, int from, int to)

from - el índice inicial del rango a copiar, incluido
to - el índice final del rango que se va a copiar, exclusivo.

De java.util.BitSet:

set(int fromIndex, int toIndex)

fromIndex - índice del primer bit a activar.
toIndex - index después del último bit que se va a establecer.

Como puede ver, parece que Java intenta hacer una convención consistente de que los límites superiores son exclusivos.

Mis preguntas son:

  • Es esta la recomendación de autoridad oficial?
  • ¿Hay violaciones notables que debamos tener cuidado?
  • ¿Hay un nombre para este sistema? (Ala "0 BASADA" vs "1-based")

ACLARACIÓN: Entiendo completamente que una colección de N objetos en un sistema de base 0 está indexado 0..N-1. Mi pregunta es que si se da un rango de (2,4), puede ser de 3 o 2, dependiendo del sistema. ¿Cómo llamas a estos sistemas?

nuevo, la cuestión no es "primer índice 0 último índice N-1" vs "primer índice 1 último índice N" sistema; eso se conoce como el sistema basado en 0 versus el basado en 1.

El problema es "Hay 3 elementos en (2,4)" frente a "Hay 2 elementos en los sistemas (2,4)". ¿Cómo llamas a estos, y es uno sancionado oficialmente sobre el otro?

+4

Se llama rango medio abierto. – fredoverflow

+0

Ah sí, ya escuché ese término. Entonces, ¿diría que las Colecciones Java están "basadas en 0 con rangos medio abiertos", entonces? – polygenelubricants

Respuesta

2

El crédito va a FredOverflow en su comentario diciendo que esto se llama el "rango medio abierto". Así que, presumiblemente, Java Collections se puede describir como "0-basado en rangos medio abiertos".

he compilado algunas discusiones sobre entreabierta vs intervalos cerrados en otra parte:


siliconbrain.com - 16 good reasons to use half-open ranges (editado por concisión):

  • El número de elementos en el rango [n, m) se solo m-n (y no m-n+1).
  • El rango vacío es [n, n) (y no [n, n-1], lo que puede ser un problema si n es un iterador que ya señala el primer elemento de una lista, o n == 0).
  • Para flotadores puede escribir [13, 42) (en lugar de [13, 41.999999999999]).
  • El +1 y -1 casi nunca se utilizan, al manejar rangos. Esto es una ventaja si son caros (como lo es para las fechas).
  • Si escribe un hallazgo en un rango, el hecho de que no se encontró nada puede indicarse fácilmente al devolver el final como la posición encontrada: if(find([begin, end)) == end) nada encontrado.
  • En los idiomas, que inician los subíndices de la matriz con 0 (como C, C++, JAVA, NCL), el límite superior es igual al tamaño.

Half-open versus closed ranges

Ventajas de rangos medio abiertas:

  • rangos vacíos son válidas: [0 .. 0]
  • Fácil para el sub-intervalos para ir al final de la original: [x .. $]
  • fácil de dividir rangos: [0 .. x] y [x .. $]

Ventajas de rangos cerrados:

  • simetría.
  • Podría decirse que es más fácil de leer.
  • ['a' ... 'z'] no requiere torpe + 1 después de 'z'.
  • [0 ... uint.max] es posible.

Este último punto es muy interesante. Es realmente incómodo escribir un predicado numberIsInRange(int n, int min, int max) con un rango medio abierto si Integer.MAX_VALUE podría estar legalmente en un rango.

2

Es solo 0 a n-1 basado.

Una lista/matriz contiene elementos 0-9 indexado.

no se puede tener una lista basada 0 indexada que es 0-n donde n es el cout, que incluye un elemento que no existe ...

Esta es la forma típica de las cosas funcionan.

  1. .
  2. Excel Rangos/Hojas/Libros de trabajo.
  3. Index (information technology)
+0

Entiendo que una colección de objetos 'N' en un sistema basado en 0 está indexada 0..N-1. Mi pregunta es si un rango (2,4) dado, ¿son 3 elementos o 2? – polygenelubricants

+0

+1 para una buena respuesta de OP – stacker

+0

Eso dependerá del contexto de la lista de objetos a la que se refiera. Como se mencionó anteriormente, la documentación * debería * ayudarlo con esto. Lo más probable es que se base en 0, pero como mencioné, hay desviaciones ... –

5

En general, sí. Si está trabajando en un lenguaje con sintaxis similar a C (C, C++, Java), las matrices tienen índice cero y la mayoría de las estructuras de datos de acceso aleatorio (vectores, listas de matrices, etc.) se indexarán en cero también.

Los índices de inicio en cero significan que el tamaño de la estructura de datos siempre será mayor que el último índice válido en la estructura de datos. La gente a menudo quiere saber el tamaño de las cosas, por supuesto, por lo que es más conveniente hablar sobre el tamaño que hablar sobre el último índice válido. La gente se acostumbra a hablar sobre índices finales de manera exclusiva, porque una matriz a[] que tiene n elementos tiene su último elemento válido en a[n-1].

Otra ventaja es utilizar un índice exclusivo para el índice final, que es que puede calcular el tamaño de una sublista restando el índice inicial inclusivo del índice final exclusivo. Si llamo al myList.sublist(3, 7), entonces obtengo una sublista con 7 - 3 = 4 elementos en ella. Si el método sublist() hubiera usado índices inclusivos para ambos extremos de la lista, entonces tendría que agregar un 1 adicional para calcular el tamaño de la sublista.

Esto es particularmente útil cuando el índice de inicio es una variable: Obtener la sublista de myList que comienza en i que tiene 5 elementos es solo myList.sublist(i, i + 5).

Dicho todo esto, usted debe siempre leer la documentación de la API, en lugar de asumir que un índice inicial dado o índice final será inclusivo o exclusivo. Del mismo modo, debe documentar su propio código para indicar si los límites son inclusivos o exclusivos.

+0

+1 para "siempre debe leer la documentación de la API" y "debe documentar su propio código para indicar" –

+0

Solo para aclarar la relevancia de el OP, creo que la popularidad de los rangos medio abiertos en Java proviene directamente del uso de rangos medio abiertos en C, que a su vez viene como una extensión natural de la indexación basada en cero. Por lo tanto, creo que una discusión de indexación basada en cero * es * relevante para la pregunta original. (Dicho esto, es mi culpa si no establecí esa conexión entre la indexación basada en cero y los rangos medio abiertos explícitos en mi respuesta original.) –

0

Esta práctica fue introducida por Josh Bloch a Collections API como un contrato.

Después de eso se convirtió en un estándar en Java y cuando alguien decide crear una biblioteca pública, asume que debe cumplir el contrato porque los usuarios esperan ver un comportamiento ya conocido en las nuevas bibliotecas.

+2

¿Entonces este es el "sistema de Bloch", entonces? Seguramente esto debe haber tenido un uso histórico antes de Java/Java Collections Framework? – polygenelubricants

+1

No sé su nombre y no estoy seguro de que exista. Vi un video en youtube donde Josh Bloch estaba hablando de buenos principios en el diseño de API. Y allí dijo que * el límite inferior inclusivo y el principio de límite superior exclusivo * es en realidad un estándar y no debería ser violado alguna vez cuando se desarrollan bibliotecas públicas. También mencionó que fue el primero (o uno de los primeros, no recuerdo) que lo introdujo en Java. – Roman

+0

@Downvoter: ¿con qué parte de mi respuesta no está de acuerdo? – Roman

0

Los índices en matriz como las estructuras de datos siempre están basadas en 0. El String está básicamente respaldado por un char[]. El marco de Colecciones se basa en matrices, etc. Esto hace que el diseño/mantenimiento/uso de la API sea más fácil sin cambiar el modo "bajo la capucha" para acceder a los elementos deseados en la matriz.

Sin embargo, existen algunas "excepciones", como los métodos de parámetros basados ​​en parameterindex de PreparedStatement y los métodos getter basados ​​en columnindex de ResultSet. Están basados ​​en 1. Detrás de las escenas tampoco representan una gran variedad de valores.

Esto probablemente plantearía una nueva pregunta: "¿Por qué los índices de matriz están basados ​​en cero?". Ahora, nuestro respetado científico de programación informática E.W. Dijkstra explica here por qué debería comenzar con cero.

0

La manera fácil de pensar en rangos medio abiertos es esta: el primer término identifica el inicio de los elementos dentro del rango, y el segundo término identifica el inicio de los elementos después del rango. Tenlo en cuenta, y todo tiene mucho más sentido. Además, la aritmética funciona mejor en muchos casos, por la respuesta de @polygenelubricants.

Cuestiones relacionadas