循环条件适用于原始迭代器,但不适用于迭代器解引用

时间:2020-07-02 05:12:18

标签: c++ c++11 while-loop iterator

在下面的代码段中, while(litr < = ritr)运作良好,但是 while(*litr < *ritr)无法满足并且超出范围,并且在尝试搜索向量中不存在的元素时会崩溃。 我了解,循环可与原始迭代器一起使用,但为什么迭代器取消引用不能满足循环条件

bool binarySearch(std::vector<int> sorted_list, int item)
{
    if(sorted_list.empty())
    {
        return false;
    }
    
    auto litr = sorted_list.begin();
    auto ritr = sorted_list.end()-1;

    while(litr <= ritr)
    {
        int leftindex = std::distance(sorted_list.begin(), litr);
        int rightindex = std::distance(sorted_list.begin(), ritr);

        int mid = (leftindex + ((rightindex-leftindex)/2));

        if(sorted_list.at(mid) == item)
        {
            return true;
        }

        if(item < sorted_list.at(mid))
        {
            ritr = sorted_list.begin() + mid-1;
        }
        else
        {
            litr = sorted_list.begin()+ mid+1;

        }
    }

    return false;
}

1 个答案:

答案 0 :(得分:1)

我不明白您所说的“迭代器扣除”是什么意思。我认为您的意思是“取消引用”?

无论如何,您要问的是JoinNode(有效)与AccumulateNode(失败)相比。有几个区别。

LessThanOrEqual与相等

工作代码使用while(litr <= ritr)而不是while(*litr < *ritr),并且等号部分对于正确操作是必需的。

考虑一个仅包含三个元素(0、10、20)的序列,搜索项为20。然后leftindex = 0,mid = 1,rightindex =2。搜索项大于mid,因此下一个索引值是leftindex = 2,rightindex =2。如果比较中没有相等值,则循环在此处结束,该函数返回false,这是错误的。循环条件必须为<=,以便循环再次执行并找到该项目。

迭代器比较与取消引用迭代器

在循环条件中使用<时,在某些情况下取消引用end()迭代器是一个问题。

考虑一个仅包含两个元素(0、10)的序列,搜索项为20。然后leftindex = 0,mid = 0,rightindex =1。搜索项大于mid,因此下一个值为leftindex = 1,rightindex =1。在此循环上,搜索项仍然大于mid,因此下一个值为leftindex = 2,rightindex =1。请注意,leftindex为2,等于end()。如果循环条件使用<=,则可以。但是,如果循环条件使用<=,则取消引用最终迭代器的尝试是未定义的行为。

begin()之前的迭代器

类似于上述内容,请考虑仅包含两个元素(0、10)的序列,搜索项为-10。然后leftindex = 0,mid = 0,rightindex =1。搜索项小于mid,因此下一个值为leftindex = 0,rightindex = -1。仅将迭代器设置为此值是未定义的行为。显然,取消引用也是未定义的行为。

请注意,即使您的“有效”版本litr <= ritr也存在此问题。您将需要其他一些代码来防止这种情况。

其他

您的代码执行*litr <= *ritr,因此假定排序列表中至少有一个元素。您应该修改代码以处理空列表的情况。