C++ 顺序容器| | C和#x2B+;入门第五版练习9.22

C++ 顺序容器| | C和#x2B+;入门第五版练习9.22,c++,iterator,containers,sequential,C++,Iterator,Containers,Sequential,我对这个练习感到困惑 练习9.22:假设iv是整数向量,下面的程序有什么问题?您可以如何纠正这些问题 在这种情况下的第一个问题是,插入向量很可能会立即使迭代器失效。 我们可以使用一个列表,但是不能使用迭代器算法来计算mid。 仅计算一次mid(如示例中所示)是不够的,因为在类似a.)的列表中,它会指向3并一直指向3,仅仅因为我们调用了迭代器mid并用mid中的元素初始化了它并不意味着在所有这些插入之后它仍然指向mid 以下是我所做的: vector<int>::iterator it

我对这个练习感到困惑

练习9.22:假设iv是整数向量,下面的程序有什么问题?您可以如何纠正这些问题

在这种情况下的第一个问题是,插入向量很可能会立即使迭代器失效。 我们可以使用一个列表,但是不能使用迭代器算法来计算mid。 仅计算一次mid(如示例中所示)是不够的,因为在类似a.)的列表中,它会指向3并一直指向3,仅仅因为我们调用了迭代器mid并用mid中的元素初始化了它并不意味着在所有这些插入之后它仍然指向mid

以下是我所做的:

vector<int>::iterator iter=iv.begin();

while(iter!=iv.begin()+iv.size()/2){    //calculating mid each time
    if(*iter==some_val)
        iv.insert(iter,2*some_val);

    iter=iv.begin();                        //revalidate iter
    while(*iter!=some_val)                  //find the original first element
        ++iter;
}
vector::迭代器iter=iv.begin();
而(iter!=iv.begin()+iv.size()/2){//每次计算mid
如果(*iter==某个值)
iv.插入(国际热核实验堆,2*部分数值);
iter=iv.begin();//重新验证iter
while(*iter!=some_val)//查找原始的第一个元素
++iter;
}
我看到这个练习是如何迫使您考虑使用哪个顺序容器,以及迭代器在不断增长的容器中的行为,但是这个练习的呈现方式仍然让我感到困惑。我是否遗漏了一些明显的要点


PS:因为整章都是关于顺序容器的,所以我没有把重点放在while循环中的条件所产生的问题上(就像他们忘记了几章前所教的一切)。

原始代码没有前进,并且使所有使用的迭代器无效

 vector<int>::iterator iter = iv.begin(),
                          mid  = iv.begin() + iv.size()/2;

 while(iter != mid)
         if(*iter == some_val)
                  iv.instert(iter, 2 * some_val);
vector::迭代器iter=iv.begin(),
mid=iv.begin()+iv.size()/2;
而(国际热核聚变实验堆!=mid)
如果(*iter==某个值)
iv.国际热核实验堆(iter,2*部分);
还有更多的问题

vector<int>::iterator iter = iv.begin(),
                      mid  = iv.begin() + iv.size()/2;
int s = iv.size()/2; // assuming we should stop at the original position

while(iter != iv.begin() + s) { // update end condition if that is the intended function
     if(*iter == some_val) {
              iter = iv.instert(iter, 2 * some_val); // gets new valid iter
              ++s; // update position of mid 
              ++iter; // skips the inserted
     }
     ++iter; // advance in vector.
}
vector::迭代器iter=iv.begin(),
mid=iv.begin()+iv.size()/2;
int s=iv.size()/2;//假设我们应该停在原来的位置
while(iter!=iv.begin()+s){//如果这是预期的函数,则更新结束条件
如果(*iter==某个值){
iter=iv.insert(iter,2*some_val);//获取新的有效iter
++s、 //更新mid的位置
++iter;//跳过插入的
}
++iter;//矢量方面的进展。
}

让我们一步一步地浏览程序,并将代码样式更新为现代C++:

auto iter = iv.begin(); // type will be std::vector<int>::iterator
const auto mid  = iv.begin() + iv.size()/2; // type will be std::vector<int>::iterator

while(iter != mid)
{
  if(*iter == some_val)
    iv.insert(iter, 2 * some_val);
}
但这仍然给我们留下了
mid
。您的问题中没有足够的信息修复此位,但可能的选项有:

while(std::distance(iter, iv.end()) > iv.size()) // shift the middle when the vector grows

const auto half = iv.size()/2;
while(std::distance(iter, iv.begin()) < half) // only iterate until iter is halfway the original length by insertion
while(std::distance(iter,iv.end())>iv.size()//当向量增长时,将中间移动
const auto half=iv.size()/2;
while(std::distance(iter,iv.begin())
因此,示例解决方案可能如下所示:

auto iter = iv.begin();

while(std::distance(iter, iv.begin()) < iv.size()/2) // iterate until halfway the current vector
{
  if(*iter == some_val)
    iter = iv.insert(iter, 2 * some_val);
  else
    ++iter;
}
autoiter=iv.begin();
而(std::distance(iter,iv.begin())

但这当然可能不是预期的解决方案。

我认为整个练习的重点只是迭代器的失效。你可能想看看有什么回报。我注意到的第一件事是
iv.insert
。不过,这可能不是我们想要的问题。另外,非常有帮助,谢谢!我很高兴我不是唯一一个认为这个问题缺乏信息的人。@JWD好吧,这个问题本身可能是故意搞不清楚的,目的是激发你大脑的内部运作,或者在课堂上引发讨论。把它放在下面:“创造性地思考代码”
;-)++iter和++s使(iter!=iv.begin()+s)成为一个条件,如果(*iter==some_val),则该条件永远不会变为真。我仍然喜欢你的回答,因为它使我最清楚地了解了这个练习的可能意图@JWD,你是对的,我需要跳过插入的,然后前进,但这只是对练习意图的一种可能解释。
iter = iv.insert(iter, 2*some_val);
while(std::distance(iter, iv.end()) > iv.size()) // shift the middle when the vector grows

const auto half = iv.size()/2;
while(std::distance(iter, iv.begin()) < half) // only iterate until iter is halfway the original length by insertion
auto iter = iv.begin();

while(std::distance(iter, iv.begin()) < iv.size()/2) // iterate until halfway the current vector
{
  if(*iter == some_val)
    iter = iv.insert(iter, 2 * some_val);
  else
    ++iter;
}