Всегда ли верхние границы индексированных диапазонов считаются эксклюзивными?

так в Java, когда индексированное диапазон, верхняя-почти всегда эксклюзив.

С java.lang.String:

substring(int beginIndex, int endIndex)

возвращает новую строку, которая является подстрокой данной строки. Подстрока начинается с указанного beginIndex и распространяется на символ в index endIndex - 1

С java.util.Arrays:

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

from - начальный индекс диапазона для копирования, включительно
to - окончательный индекс диапазона для копирования, эксклюзив.

С java.util.BitSet:

set(int fromIndex, int toIndex)

fromIndex - индекс Первого БИТа, который нужно установить.
toIndex - индекс после последнего бита, который будет установлен.

как вы можете видеть, похоже, что Java пытается сделать его согласованным соглашением, которое верхнее границы являются эксклюзивными.

мои вопросы:

  • это официальная авторитетная рекомендация?
  • есть ли заметные нарушения, которых мы должны опасаться?
  • есть ли название для этой системы? (ala "0-based" vs "1-based")

уточнение: я полностью понимаю, что коллекция N объекты в 0-система индексации 0..N-1. Мой вопрос в том, что если диапазон (2,4) дано, может быть либо 3 пункта, либо 2, в зависимости от системы. Как вы называете эти системы?

опять же, проблема не в " первом индексе 0 последний индекс N-1 " vs " первый индекс 1 последний индекс N" система; это известно как система на основе 0 против 1.

вопрос "Есть 3 элемента в (2,4) " vs " есть 2 элемента в (2,4)" системы. Как вы это называете, и одно официально санкционировано над другим?

6 ответов


в общем, да. Если вы работаете на языке С c-подобным синтаксисом (C, C++, Java), то массивы имеют нулевую индексацию и большинство структур данных произвольного доступа (векторы, списки массивов и т. д.) также будут проиндексированы на ноль.

стартовые показатели на ноль означает, что размер структуры данных всегда будет на один больше, чем последний допустимый индекс в структуре данных. Люди часто хотят знать размер вещей, конечно, и поэтому удобнее говорить о размер, чем говорить о последнем действительном индексе. люди привыкают говорить о конечных индексах эксклюзивным образом, потому что массив a[] что это n elements long имеет последний допустимый элемент в a[n-1].

есть еще одно преимущество использования эксклюзивного индекса для конечного индекса, которое заключается в том, что вы можете вычислить размер подсписка, вычитая инклюзивный начальный индекс из эксклюзивного конечного индекса. Если я позову myList.sublist(3, 7), затем я получаю подсписок с 7 - 3 = 4 элементов в нем. Если sublist() метод использовал инклюзивные индексы для обоих концов списка, тогда мне нужно было бы добавить дополнительный 1 для вычисления размера подсписка.

это особенно удобно, когда начальный индекс является переменной: получение подсписке myList начиная с i то есть 5 элементов длиной просто myList.sublist(i, i + 5).

все это, как говорится, вы должны всегда прочитайте документацию API, а не чем предполагать, что данный начальный или конечный индекс будет инклюзивным или эксклюзивным. Аналогично, вы должны документировать свой собственный код, чтобы указать, являются ли какие-либо границы включительными или исключительными.


просто от 0 до n-1 на основе.

список/массив содержит 10 предметы 0-9 индексируется.

У вас не может быть 0 индексированного списка, который равен 0-n, где cout равен n, который включает элемент, который не существует...

Это типичный метод работы.

  1. да.
  2. Диапазоны Excel / Листы / Книги.
  3. (информация технология)

кредит идет к FredOverflow в его комментарии, говоря, что это называется "полуоткрытым диапазоном". Таким образом, предположительно, коллекции Java можно описать как"0-на основе полуоткрытых диапазонов".

я собрал некоторые обсуждения о полуоткрытых и закрытых диапазонах в другом месте:


siliconbrain.com -16 веских причин использовать полуоткрытые диапазоны (отредактировано для краткости):

  • количество элементов в диапазоне [n, m) Это просто m-n (а не m-n+1).
  • пустой диапазон [n, n) (а не [n, n-1], который может быть проблемой, если n является итератором, уже указывающим первый элемент списка, или если n == 0).
  • для поплавков вы можете написать [13, 42) (вместо [13, 41.999999999999]).
  • на +1 и -1 почти никогда не используются при обработке диапазонов. Это преимущество, если они дорогие (как и для дат).
  • если вы пишете находку в диапазоне, тот факт, что ничего не было найдено, можно легко указать, вернув конец как найденную позицию:if( find( [begin, end) ) == end) ничего не найдено.
  • в языках, которые запускают индексы массива с 0 (например, C, C++, JAVA, NCL), верхняя граница равна размеру.

полуоткрытые и закрытые диапазоны

преимущества полуоткрытых диапазонов:

  • пустой допустимые диапазоны:[0 .. 0]
  • легко для поддиапазонов, чтобы перейти к концу оригинала:[x .. $]
  • легко разделить диапазоны: [0 .. x] и [x .. $]

преимущества закрытых диапазонов:

  • симметрии.
  • возможно, легче читать.
  • ['a' ... 'z'] не требует неудобных + 1 после 'z'.
  • [0 ... uint.max] возможно.

этот последний момент очень интересен. Это действительно неудобно писать numberIsInRange(int n, int min, int max) предикат с полуоткрытым диапазоном if Integer.MAX_VALUE может быть юридически в ассортименте.


эта практика была введена Джошем Блохом в Collections API в качестве контракта.

после этого он стал стандартом в java, и когда кто-то dicide для создания публичной библиотеки он предполагает, что он должен сохранить контракт, потому что пользователи ожидают увидеть уже известное поведение в новых библиотеках.


индексы в массив datastructures действительно всегда основаны на 0. The String в основном поддерживается char[]. Каркас коллекций находится под капотом на основе массивов и так далее. Это упрощает проектирование/обслуживание / использование API без изменения способа" под капотом " для доступа к желаемому элементу(элементам) в массиве.

однако есть некоторые "исключения", такие как методы сеттера на основе parameterindex PreparedStatement и методы геттера на основе columnindex ResultSet. Они основаны на 1. За кулисами они также не представляют собой массив значений.

это, вероятно, вызовет новый вопрос: "почему индексы массива основаны на нуле?". Итак, наш уважаемый ученый-программист!--15-->У. Э. Дейкстра объясняется здесь почему он должен начать с нуля.


простой способ думать о полуоткрытых диапазонах таков: первый термин идентифицирует начало элементов в диапазоне, а второй термин идентифицирует начало элементов после диапазона. Имейте это в виду, и все это имеет гораздо больше смысла. Плюс арифметика во многих случаях работает лучше, за ответ @polygenelubricants.