索引范围的上限始终假定为独占?

pol*_*nts 7 java indexing collections range

所以在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试图使其成为上限是独占的一致约定.

我的问题是:

  • 这是官方权威推荐吗?
  • 是否存在我们应该警惕的明显违规行为?
  • 这个系统有名字吗?(ala"0-based"vs"1-based")

澄清:我完全理解N基于0的系统中的对象集合已被索引0..N-1.我的问题是,如果(2,4)给定范围,它可以是3项或2,具体取决于系统.你怎么称呼这些系统?

再次,问题不是"第一指数0最后指数N-1"与"第一指数1最后指数N"制度; 这就是所谓的基于0和基于1的系统.

问题是"有3个元素(2,4)"与"系统中有2个元素(2,4)".你怎么称呼这些,并且正式批准另一个?

Joe*_*han 5

一般来说,是的.如果您使用的是具有类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文档,而不是假设给定的开始索引或结束索引将是包容性的或排他性的.同样,您应该记录自己的代码,以指示是否包含任何边界或独占.


pol*_*nts 3

FredOverflow 在他的评论中表示这被称为“半开范围”。所以想必,Java Collections 可以被描述为“基于 0 的半开范围”。

我在其他地方整理了一些关于半开放与封闭范围的讨论:


Siliconbrain.com - 使用半开范围的 16 个充分理由(为简洁起见进行了编辑):

  • 该范围内的元素数量[n, m)m-n(而不是m-n+1)。
  • 空范围是[n, n)(而不是,如果是迭代器已经指向列表的第一个元素,或者 if ,[n, n-1]这可能会出现问题)。nn == 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)半开范围的谓词确实很尴尬。Integer.MAX_VALUE