在 std::unique 之后重新排列矢量元素
Rearranged vector elements after std::unique
我目前正在研究 Stanley Lippman 的 C++ Primer。第 10 章介绍了泛型算法。
例如 std::sort
、std::unique
和 std::vector
成员函数 erase
应用于删除向量中的重复元素。
为了查看矢量元素如何被 std::unique 重新排列,我尝试打印每个元素,结果发现并非所有元素都被打印出来。然而,调用 .size()
表明向量的大小如预期的那样没有变化。
编译程序后:
clang++ -std=c++11 -o elimDubs elimDubs.cc
并使用
调用程序
./elimDubs the quick red fox jumps over the slow red turtle
程序打印
Size after std::unique: 10
fox jumps over quick red slow the turtle the
这只是 10 个元素中的 9 个。 (缺少 red
)
为什么?对于程序来说,这并不重要,因为随后调用 erase
无论如何都会用于删除重复的元素,但仍然让我恼火的是缺少或至少没有打印元素。
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
void elimDubs( std::vector<std::string> &words )
{
std::sort( words.begin(), words.end() );
auto end_unique = std::unique( words.begin(), words.end() );
std::cout << "Size after std::unique: "
<< words.size() << std::endl;
for ( const auto &el : words )
std::cout << el << " ";
std::cout << std::endl;
}
int main(int argc, char **argv)
{
std::vector<std::string> sentence;
if ( argc < 2 )
return -1;
std::copy( argv + 1, argv + argc,
std::back_inserter(sentence) );
elimDubs( sentence );
}
std::unique
是一个破坏性的过程。引用 cppreference,
Removing is done by shifting the elements in the range in such a way that elements to be erased are overwritten.
这意味着 std::unique
返回的新结束迭代器之后的任何元素都将处于有效但未指定的状态。它们不应该被访问,因为它们应该通过调用 erase
.
从向量中删除
这个在注释部分也有注明:
Iterators in [r, last)
(if any), where r
is the return value, are still dereferenceable, but the elements themselves have unspecified values. A call to unique
is typically followed by a call to a container's erase
member function, which erases the unspecified values and reduces the physical size of the container to match its new logical size.
还有10个元素;只是其中一个被“移走了”。如果您更改打印循环以引用单词,则:
for ( const auto &el : words )
std::cout << "'" << el << "'" << " ";
您将看到以下输出:
'fox' 'jumps' 'over' 'quick' 'red' 'slow' 'the' 'turtle' 'the' ''
我目前正在研究 Stanley Lippman 的 C++ Primer。第 10 章介绍了泛型算法。
例如 std::sort
、std::unique
和 std::vector
成员函数 erase
应用于删除向量中的重复元素。
为了查看矢量元素如何被 std::unique 重新排列,我尝试打印每个元素,结果发现并非所有元素都被打印出来。然而,调用 .size()
表明向量的大小如预期的那样没有变化。
编译程序后:
clang++ -std=c++11 -o elimDubs elimDubs.cc
并使用
调用程序./elimDubs the quick red fox jumps over the slow red turtle
程序打印
Size after std::unique: 10
fox jumps over quick red slow the turtle the
这只是 10 个元素中的 9 个。 (缺少 red
)
为什么?对于程序来说,这并不重要,因为随后调用 erase
无论如何都会用于删除重复的元素,但仍然让我恼火的是缺少或至少没有打印元素。
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
void elimDubs( std::vector<std::string> &words )
{
std::sort( words.begin(), words.end() );
auto end_unique = std::unique( words.begin(), words.end() );
std::cout << "Size after std::unique: "
<< words.size() << std::endl;
for ( const auto &el : words )
std::cout << el << " ";
std::cout << std::endl;
}
int main(int argc, char **argv)
{
std::vector<std::string> sentence;
if ( argc < 2 )
return -1;
std::copy( argv + 1, argv + argc,
std::back_inserter(sentence) );
elimDubs( sentence );
}
std::unique
是一个破坏性的过程。引用 cppreference,
Removing is done by shifting the elements in the range in such a way that elements to be erased are overwritten.
这意味着 std::unique
返回的新结束迭代器之后的任何元素都将处于有效但未指定的状态。它们不应该被访问,因为它们应该通过调用 erase
.
这个在注释部分也有注明:
Iterators in
[r, last)
(if any), wherer
is the return value, are still dereferenceable, but the elements themselves have unspecified values. A call tounique
is typically followed by a call to a container'serase
member function, which erases the unspecified values and reduces the physical size of the container to match its new logical size.
还有10个元素;只是其中一个被“移走了”。如果您更改打印循环以引用单词,则:
for ( const auto &el : words )
std::cout << "'" << el << "'" << " ";
您将看到以下输出:
'fox' 'jumps' 'over' 'quick' 'red' 'slow' 'the' 'turtle' 'the' ''