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

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

От java.lang.String:

substring(int beginIndex, int endIndex)

Возвращает новую строку, которая является подстрокой этой строки. Подстрока начинается в указанном beginIndex и расширяется на символ в индексе 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 пытается сделать это последовательной конвенцией, что верхние границы эксклюзивны.

Мои вопросы:

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

РАЗЪЯСНЕНИЕ: Я полностью понимаю что набор N объекты в системе на основе 0 индексируются 0..N-1. Мой вопрос - это если диапазон (2,4) данный, это могут быть или 3 объекта или 2, в зависимости от системы. Что Вы называете этими системами?

СНОВА, проблемой не является "первый индекс 0 последний индекс N-1"по сравнению с "первым индексом 1 последний индекс N"система; это известно как на основе 0 по сравнению с системой на основе 1.

Проблема "Существует 3 элемента в (2,4)"по сравнению с "Существует 2 элемента в (2,4)"системы. Что Вы называете ими, и каждый официально санкционирован по другому?

7
задан polygenelubricants 13 March 2010 в 22:52
поделиться

6 ответов

Заслуга принадлежит FredOverflow в его комментарии, где говорится, что это называется "полуоткрытый диапазон". Так что, предположительно, Java Collections можно описать как "0-based with half-open ranges".

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


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. Это является преимуществом, если они дороги (как в случае с датами).
  • Если вы пишете find в диапазоне, то тот факт, что ничего не найдено, можно легко указать, вернув конец в качестве найденной позиции: 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) с полуоткрытым диапазоном, если Integer.MAX_VALUE может быть легально в диапазоне.

2
ответ дан 7 December 2019 в 03:14
поделиться

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

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

0
ответ дан 7 December 2019 в 03:14
поделиться

Индексы в массиве , такие как структуры данных, действительно всегда отсчитываются от нуля. Строка в основном поддерживается char [] . Фреймворк коллекций находится под капотом на основе массивов и так далее. Это упрощает разработку / поддержку / использование API без изменения «скрытого» способа доступа к желаемому элементу (ам) в массиве.

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

Это, вероятно, вызовет новый вопрос: «Почему индексы массива основаны на нуле?». Наш уважаемый ученый-программист Э.У. Дейкстра объясняет здесь , почему он должен начинаться с нуля.

0
ответ дан 7 December 2019 в 03:14
поделиться

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

0
ответ дан 7 December 2019 в 03:14
поделиться

В целом да. Если вы работаете на языке с синтаксисом, подобным C (C, C ++, Java), то массивы имеют нулевой индекс, а большинство структур данных с произвольным доступом (векторы, списки массивов и т. Д.) Будут иметь нулевой индекс. также.

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

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

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

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

5
ответ дан 7 December 2019 в 03:14
поделиться

Его просто от 0 до n-1 .

Список / массив содержит 10 элементов 0–9 проиндексированных.

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

Это типичный способ работы.

  1. Да .
  2. Диапазоны / Таблицы / Рабочие тетради Excel.
  3. Указатель (информационные технологии)
2
ответ дан 7 December 2019 в 03:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: