C++ 为什么';t std::删除数组的最后一个元素
可能重复:C++ 为什么';t std::删除数组的最后一个元素,c++,C++,可能重复: 对不起,我是C++11和迭代器的新手。这应该会删除数组中的所有数字3,但不会删除最后一个。为什么? #include <algorithm> #include <array> #include <iostream> int main() { std::array<int, 8> a{{9, 3, 4, 5, 33, 5, 6, 3}}; int N(3); std::remove(a.begin(), a.e
对不起,我是C++11和迭代器的新手。这应该会删除数组中的所有数字3,但不会删除最后一个。为什么?
#include <algorithm>
#include <array>
#include <iostream>
int main() {
std::array<int, 8> a{{9, 3, 4, 5, 33, 5, 6, 3}};
int N(3);
std::remove(a.begin(), a.end(), N);
for (int i : a) {
std::cout << i << '\n';
}
}
std::remove
操作迭代器;因此,它实际上无法从容器中删除元素。这就是为什么它通常与擦除一起使用的原因:
a.erase(std::remove(a.begin(), a.end(), N), a.end());
正如其他人所指出的,这对迭代器上的
数组std::remove
操作不起作用;因此,它实际上无法从容器中删除元素。这就是为什么它通常与擦除一起使用的原因:
a.erase(std::remove(a.begin(), a.end(), N), a.end());
正如其他人所指出的,这不适用于数组算法不了解底层容器。它们只是根据给定的迭代器进行迭代,并独立于包含它们的容器访问元素。这就是为什么有一种称为“擦除-删除”的习惯用法,它采用以下模式:
container.erase(std::remove(it1, it2, value), std::end(container));
std::remove
将保留的元素移到前面(谢谢,K-ballo),并将迭代器返回到未移动元素的开头。然后,erase
将从该点一直擦除所有内容
由于std::array
封装了一个固定大小的数组,因此我将把您的示例改编为std::vector
:
std::vector<int> v{9, 3, 4, 5, 33, 5, 6, 3};
v.erase(std::remove(std::begin(v), std::end(v), 3), std::end(v));
std::向量v{9,3,4,5,33,5,6,3};
v、 擦除(std::remove(std::begin(v)、std::end(v)、3)、std::end(v));
唯一需要注意的是.begin()
和.end()
的更一般形式,它也适用于内置阵列。这包含在C++11中。算法不了解底层容器。它们只是根据给定的迭代器进行迭代,并独立于包含它们的容器访问元素。这就是为什么有一种称为“擦除-删除”的习惯用法,它采用以下模式:
container.erase(std::remove(it1, it2, value), std::end(container));
std::remove
将保留的元素移到前面(谢谢,K-ballo),并将迭代器返回到未移动元素的开头。然后,erase
将从该点一直擦除所有内容
由于std::array
封装了一个固定大小的数组,因此我将把您的示例改编为std::vector
:
std::vector<int> v{9, 3, 4, 5, 33, 5, 6, 3};
v.erase(std::remove(std::begin(v), std::end(v), 3), std::end(v));
std::向量v{9,3,4,5,33,5,6,3};
v、 擦除(std::remove(std::begin(v)、std::end(v)、3)、std::end(v));
唯一需要注意的是.begin()
和.end()
的更一般形式,它也适用于内置阵列。这包含在C++11中。正如其他人指出的,std::remove()
不会删除任何元素。如果需要使用std::array
,您仍然可以使用std::remove()
,只需捕获相应的迭代器即可确定序列的结尾。我不知道您是如何获得声明的输出(带卷曲和逗号)的,但下面是我如何实现它的:
auto end = std::remove(a.begin(), a.end(), 3);
std::cout << "{ ";
if (a.begin() != end) {
std::copy(a.begin(), end - 1, std::ostream_iterator<int>(std::cout, ", "));
std::cout << end[-1];
}
std::cout << "}\n";
auto-end=std::remove(a.begin(),a.end(),3);
std::cout正如其他人指出的,std::remove()
不会删除任何元素。如果需要使用std::array
,您仍然可以使用std::remove()
,只需捕获相应的迭代器即可确定序列的结尾。我不知道您是如何获得声明的输出(带卷曲和逗号)的,但下面是我如何实现它的:
auto end = std::remove(a.begin(), a.end(), 3);
std::cout << "{ ";
if (a.begin() != end) {
std::copy(a.begin(), end - 1, std::ostream_iterator<int>(std::cout, ", "));
std::cout << end[-1];
}
std::cout << "}\n";
auto-end=std::remove(a.begin(),a.end(),3);
std::coutstd::array
无法更改其大小。使用std::vector
。std::array
无法更改其大小。使用std::vector
。remove
不会将删除的元素移到后面,而是将保留的元素移到前面。后面的元素有一个未指定的值。@K-ballo,哦,我没意识到。我快忘了。我稍后再修复。remove
不会将删除的元素移到后面,而是将保留的元素移到前面。后面的元素有一个未指定的值。@K-ballo,哦,我没意识到。我快忘了。稍后我会修复它。在这种情况下,std::remove
在做什么?我知道它返回了一个迭代器,但这(除了给它的参数外)如何影响erase
处理它呢?@David:chris在他的回答中解释得很好。如果您阅读参考,那么remove
所做的就是将所有保留的元素移到前面,有效地移除您想要移除的元素,并将所有实际用途都是垃圾的元素留在序列的后面。erase
所做的是清理remove
留下的垃圾。在这种情况下,std::remove
在做什么?我知道它返回了一个迭代器,但这(除了给它的参数外)如何影响erase
处理它呢?@David:chris在他的回答中解释得很好。如果您阅读参考,那么remove
所做的就是将所有保留的元素移到前面,有效地移除您想要移除的元素,并将所有实际用途都是垃圾的元素留在序列的后面。擦除
所做的是清除删除
留下的垃圾。