【问题标题】:Why is the C++ sort range [first, last)? [duplicate]为什么 C++ 排序范围是 [first, last)? [复制]
【发布时间】:2018-09-15 16:05:02
【问题描述】:

也许他们想帮助我们,考虑到数组从 0 开始。所以我们可能会认为,如果我们想对前 n 个元素进行排序,我们会一直到 v[n],但实际上我们只去 v [n-1]。所以这可以解释函数排序到最后 - 1 的事实。但在这种情况下,为什么它不从第一个开始 - 1?在乞求时,我们输入 1 并从 v[1] 开始,然后我们输入 n 并在 v[n-1] 处停止。为什么?如果它确实从一个考虑数组,它应该包括最后一个元素。这些只是我的——可能是愚蠢的——想法?这就是为什么我会欣赏一个真实的解释。谢谢!

编辑:非常感谢大家的回答。我可以看到有很多优点,在这个范围内一切看起来都比较正常。我会尽量记住你所有的例子,以便在我的脑海中清楚地表达出来。

【问题讨论】:

  • 为什么不从零开始呢?如果你不使用它,你会丢失一个索引值。
  • 在 C++ 中自始至终都使用包含下限和互斥上限,那么为什么要为 sort 例外?
  • 这不仅仅是排序,结束后的原则几乎会在任何地方跟随你......结束后有一个优势:你总是通过 start + size 获得范围的结束而无需减去一个 - 或者,反过来,你得到最后的大小 - 开始而不必添加一个。
  • 如果我没记错的话,这种模式允许内部循环通过只检查等于而不是小于或等于限制来提高效率。
  • 如果范围包含在内,你将如何表示一个空范围?

标签: c++ algorithm sorting


【解决方案1】:

这样做是为了与标准 C++ 库的所有容器中的迭代器语义保持一致:begin() 始终是包含的,而 end() 始终是排除的,因为它“指向”紧随容器末尾之后的位置.

这与指向数组元素的指针的行为一致:

int data[SIZE];
int *begin = data;      // Inclusive
int *end = &data[SIZE]; // Exclusive

【讨论】:

    【解决方案2】:

    以这种方式定义范围可以轻松处理子范围。这是一个愚蠢的例子:

    void apply(int* begin, int* end, void (*f)(int)) {
        if (begin == end)
            ; // nothing to do
        else if (begin + 1 == end)
            f(*begin);
        else {
            int* mid = begin + (end - begin) / 2;
            apply(begin, mid, f);
            apply(mid, end, f);
        }
    }
    

    这里有两点很重要。首先,检测空范围很简单:begin == end。其次,分成两个范围同样简单。只需生成一个中间点 mid 并将其用作每个范围的结尾:[begin, mid)[mid, end) 是两个范围,涵盖了第一个范围中的所有元素。

    现在尝试编写执行相同操作但使用双重包含或双重排除范围的代码。对比和比较。

    【讨论】:

      【解决方案3】:

      为什么 C++ 排序范围是 [first, last)?

      对于所有迭代器范围都是如此,所以我猜你是在问为什么迭代器范围通常表示为 [first, last)

      回答(或者更确切地说,回答)这个问题:为什么不呢?你认为有更好的选择吗?那是什么选择?

      假设您希望将范围表示为[first, last]。这就是迭代器需要被处理的方式:


      表示长度为1的范围。设it为迭代器:

      representation - how to treat
      [first, last)  - it, it + 1
      [first, last]  - it, it
      

      [first, last] 对单个值有更紧凑的表示。我明白为什么这看起来不错。但是+ 1 与范围的长度有明确的联系,这也很好。


      表示长度范围n

      [first, last)  - begin, begin + n
      [first, last]  - begin, begin + n - 1
      

      这就是与长度的联系显示其伟大之处的地方。 [first, last) 更简单。


      表示空范围:

      [first, last)  - it, it
      [first, last]  - it + 1, it
      

      这真是个大问题。 [first, last] 需要两个不同的迭代器值来表示一个空范围。以向量为例。您需要在第一个值之前使用迭代器,在最后一个值之后使用迭代器来表示它(因为没有指向的值)。

      【讨论】:

        猜你喜欢
        • 2018-01-26
        • 1970-01-01
        • 2021-01-13
        • 2014-04-26
        • 2020-09-21
        • 1970-01-01
        • 1970-01-01
        • 2021-11-02
        • 2017-11-02
        相关资源
        最近更新 更多