顺序容器||C++初级读本第五版练习9.22
Sequential Containers || C++ Primer Fifth Edition Exercise 9.22
我对这个练习感到困惑。
练习9.22:假设iv是int的向量,下面的程序有什么问题?您如何纠正问题?
vector<int>::iterator iter = iv.begin(),
mid = iv.begin() + iv.size()/2;
while(iter != mid)
if(*iter == some_val)
iv.insert(iter, 2 * some_val)
我要做的第一件事就是去问这个项目的意图是什么。由于我不确定这本书的这一部分是谁写的,也不想因为一些可能微不足道的事情而打扰作者,我开始猜测。
我假设他们想在向量中插入第一个值的双精度,直到值位于在中间。
那么a)矢量会这样生长吗?
{1,2,3,4,5}
{(2),1,2,3,4,5}
{2,(2),1,2,3,4,5}
{2,2,(2),1,2,3,4,5}
这种情况下的第一个问题是,插入向量很可能会立即使迭代器无效。我们可以使用列表,但不能使用迭代器算法来计算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;
}
我看到了这个练习是如何迫使你思考使用哪个顺序容器以及迭代器在不断增长的容器中的行为的,但这个练习的呈现方式仍然让我感到困惑。我错过了一些明显的要点吗?
附言:由于整章都是关于顺序容器的,我没有关注while循环中条件出现的问题(就像他们忘记了几章前教的所有内容一样)。
让我们一步一步地完成程序,并将代码样式更新为现代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);
}
前两行创建迭代器对。循环进行迭代,直到到达向量的中间。循环内的条件检查iter
所指向的位置处的值是否等于某个预定义值someval
。下一行代码将一个新项插入到向量中,该项等于some_val
值的两倍。
现在回答您的问题:插入行确实使所有迭代器无效,这确实是程序中的问题。此外,迭代器不进行迭代,因为它从不递增。通过使用insert
调用的返回值使iter
有效并可再次使用,可以解决一个无效问题:
iter = 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
因此,一个示例解决方案可能如下所示:
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;
}
但这当然可能不是预期的解决方案。
原始代码不会前进并使所有使用的迭代器无效。
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<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.
}
- 加速C++练习2.4
- C++初级读本5版1.23从文件流中读取
- 旧版c++中结构和类之间的差异
- C++入门 5 版:类消息和文件夹
- C++ 独特指针练习的向量
- 转换器练习:跳过 if 语句和 if 语句
- 在链链表中手动插入第五个元素
- 如何从向量或数组中选择最常见的数字?(前五名)C++
- 节目练习直播C++
- 代码精简版页面变为空白
- 所以我正在为我的学校作业练习继承,但我无法正确实施标题保护
- 我正在尝试一个傻瓜 C++ 练习,我遇到了一个错误,说类 'GraduateStudent' 没有任何名为 'advisor' 的字段
- C 底漆Lippman第五练习2.27 b
- C++初级读本第五版字符串练习,要求两段不同的代码提供相同的输出
- C++入门第5版练习1.19 "The If Statement"的误解 ?
- C++引物第五版 1.4.4.
- 关于C++初级读本第五版中指针的一些问题
- 顺序容器||C++初级读本第五版练习9.22
- C++初级练习2.27[第5版]
- 理解Moothy第2.21节发布的C++初级读本第五版解决方案