在下面的代码段中,
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;
}
答案 0 :(得分:1)
我不明白您所说的“迭代器扣除”是什么意思。我认为您的意思是“取消引用”?
无论如何,您要问的是JoinNode
(有效)与AccumulateNode
(失败)相比。有几个区别。
工作代码使用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()。如果循环条件使用<=
,则可以。但是,如果循环条件使用<=
,则取消引用最终迭代器的尝试是未定义的行为。
类似于上述内容,请考虑仅包含两个元素(0、10)的序列,搜索项为-10。然后leftindex = 0,mid = 0,rightindex =1。搜索项小于mid,因此下一个值为leftindex = 0,rightindex = -1。仅将迭代器设置为此值是未定义的行为。显然,取消引用也是未定义的行为。
请注意,即使您的“有效”版本litr <= ritr
也存在此问题。您将需要其他一些代码来防止这种情况。
您的代码执行*litr <= *ritr
,因此假定排序列表中至少有一个元素。您应该修改代码以处理空列表的情况。