1. 说明
  2. 1 std::unique()
    std::unique()是C++17引入,用于去除相邻的重复元素。

比较是否相等的函数,默认是使用operator==,可以自定义比较函数。

所以常用的函数签名有如下两种:

使用默认的比较函数operator==
template< class ForwardIt >
ForwardIt unique( ForwardIt first, ForwardIt last );
使用自定义的比较函数
template< class ForwardIt, class BinaryPredicate >
ForwardIt unique( ForwardIt first, ForwardIt last, BinaryPredicate p );
其中BinaryPredicate p为自定义的比较函数。

前两个参数定义了作用范围[first, last),只在作用范围内去重。
而且这个去重只是跟相邻的元素比,所以如果要整体去重,先对数组进行个排序。

函数有返回值,返回值是指向范围新结尾的迭代器。新结尾的老结尾之间的元素为不确定值,一般为原来元素的内容,尽量不要去使用。

1.2 std::unique_copy()
std::unique_copy()相对于std::unique()多了个copy操作,用于去除相邻的重复元素后,把元素复制到结果容器中去。
所以函数参数也比std::unique()多了结果容器的参数。如下:

使用默认的比较函数operator==
template< class InputIt, class OutputIt >
OutputIt unique_copy( InputIt first, InputIt last, OutputIt d_first );
其中OutputIt d_first指定了结果容器的起始迭代器。

使用自定义的比较函数
template< class InputIt, class OutputIt, class BinaryPredicate >
OutputIt unique_copy( InputIt first, InputIt last, OutputIt d_first, BinaryPredicate p );
其中BinaryPredicate p为自定义的比较函数。

从范围 [first, last) 复制元素到始于 d_first 的另一范围,使得无连续的相等元素。

注意点:

去重只是跟相邻的元素比,所以如果要整体去重,先对数组进行个排序。
放入的结果容器要有足够的容量赋值新元素,或者使用std::back_inserter()进行插入新元素
std::unique_copy()不会破坏原先数组的顺序
2. 头文件
#include

  1. 例子
  2. 1 std::unique 使用默认比较函数

    include <iostream> // std::cout</iostream>

    include <algorithm> // std::unique</algorithm>

    include <vector> // std::vector</vector>

int main()
{
std::vector<int> nums = { 10,20,20,20,30,30,20,20,10 }; // 10 20 20 20 30 30 20 20 10</int>

// using default comparison:
std::vector<int>::iterator last;
last = std::unique(nums.begin(), nums.end());   // 10 20 30 20 10 x x x x
                                                //                ^
nums.erase(last, nums.end());                   // 10 20 30 20 10

// print out content:
std::cout << "nums contains:";
for (int num : nums) {
    std::cout << ' ' << num;
}        
std::cout << std::endl;

return 0;

}
输出结果如同右边注释所示。

3.2 std::unique 使用默认自定义函数
#include <iostream> // std::cout
#include <algorithm> // std::unique
#include <vector> // std::vector</vector></algorithm></iostream>

int main()
{
std::vector<int> nums = { 10,20,20,20,30,30,20,20,10 }; // 10 20 20 20 30 30 20 20 10</int>

// using custom comparison function:
auto mycompare = [](int i, int j) { return (i == j); };
std::vector<int>::iterator last;
last = std::unique(nums.begin(), nums.end(), mycompare);   // 10 20 30 20 10 x x x x
                                                           //                ^
nums.erase(last, nums.end());                              // 10 20 30 20 10

// print out content:
std::cout << "nums contains:";
for (int num : nums) {
    std::cout << ' ' << num;
}        
std::cout << std::endl;

return 0;

}
自定义比较函数可以使用上面的lambda表达式,也可以如下定义:

bool myfunction (int i, int j) {
return (i==j);
}
输出结果如同右边注释所示。

3.3 std::unique 在类中的使用
比如加入立方体有边长和重量属性,想要去掉边长相同的相邻元素,操作如下:

include <iostream> // std::cout</iostream>

include <algorithm> // std::unique_copy</algorithm>

include <vector> // std::vector</vector>

class Cube {
public:
Cube(int length, int weight): length_(length), weight_(weight){}

// custom comparison function
bool operator==(const Cube& other) const {
    return (length_ == (other.length_));
}

int length_;
int weight_;

};

int main()
{
std::vector<cube> cubes;
cubes.push_back(Cube(10, 300));
cubes.push_back(Cube(10, 200));
cubes.push_back(Cube(20, 300));
cubes.push_back(Cube(20, 200));
cubes.push_back(Cube(30, 300));
cubes.push_back(Cube(30, 200));</cube>

std::vector<Cube>::iterator last;
last = std::unique(cubes.begin(), cubes.end());   

cubes.erase(last, cubes.end());

// print out content:
std::cout << "cubes contains:" << std::endl;
for (Cube cube : cubes) {
    std::cout << "length: " << cube.length_ << "\tweight: " << cube.weight_;
    std::cout << std::endl;
}        

return 0;

}
输出结果如下:

cubes contains:
length: 10 weight: 300
length: 20 weight: 300
length: 30 weight: 300
在类中自定义bool operator==(const Cube& other) const函数,用于判断是否是相同元素

3.3 std::unique_copy 使用默认比较函数
#include <iostream> // std::cout
#include <algorithm> // std::unique_copy
#include <vector> // std::vector</vector></algorithm></iostream>

int main()
{
std::vector<int> nums_ori = { 10,20,20,20,30,30,20,20,10 }; // 10 20 20 20 30 30 20 20 10
std::vector<int> nums_new(9); // 0 0 0 0 0 0 0 0 0</int></int>

// using default comparison:
std::unique_copy(nums_ori.begin(), nums_ori.end(), nums_new.begin());   

std::cout << "nums_ori contains:\t";
for (int num : nums_ori) {
    std::cout << ' ' << num;
}
std::cout << std::endl;

std::cout << "nums_new contains:\t";
for (int num : nums_new) {
    std::cout << ' ' << num;
}
std::cout << std::endl;

return 0;

}
输出结果如下:

nums_ori contains: 10 20 20 20 30 30 20 20 10
nums_new contains: 10 20 30 20 10 0 0 0 0
从结果容器nums_new的起始位置开始写入结果,不会破坏原先数组nums_ori

但是上面要先结果容器nums_new有足够的容量,否则数组越界。
这时可以使用std::back_inserter()来避免预先分配容量,用多少就实际插入多少,可参考 https://www.jianshu.com/p/6862a79eba0a

include <iostream> // std::cout</iostream>

include <algorithm> // std::unique_copy</algorithm>

include <vector> // std::vector</vector>

include <iterator> // std::back_inserter</iterator>

int main()
{
std::vector<int> nums_ori = { 10,20,20,20,30,30,20,20,10 }; // 10 20 20 20 30 30 20 20 10
std::vector<int> nums_new; </int></int>

// using default comparison:
std::unique_copy(nums_ori.begin(), nums_ori.end(), std::back_inserter(nums_new));

std::cout << "nums_ori contains:\t";
for (int num : nums_ori) {
    std::cout << ' ' << num;
}
std::cout << std::endl;

std::cout << "nums_new contains:\t";
for (int num : nums_new) {
    std::cout << ' ' << num;
}
std::cout << std::endl;

return 0;

}
输出结果如下:

nums_ori contains: 10 20 20 20 30 30 20 20 10
nums_new contains: 10 20 30 20 10
3.3 std::unique_copy 使用自定义比较函数
#include <iostream> // std::cout
#include <algorithm> // std::unique_copy
#include <vector> // std::vector
#include <iterator> // std::back_inserter</iterator></vector></algorithm></iostream>

int main()
{
std::vector<int> nums_ori = { 10,20,20,20,30,30,20,20,10 }; // 10 20 20 20 30 30 20 20 10
std::vector<int> nums_new; </int></int>

// using custom comparison function:
auto mycompare = [](int i, int j) { return (i == j); };
std::unique_copy(nums_ori.begin(), nums_ori.end(), std::back_inserter(nums_new), mycompare);

std::cout << "nums_ori contains:\t";
for (int num : nums_ori) {
    std::cout << ' ' << num;
}
std::cout << std::endl;

std::cout << "nums_new contains:\t";
for (int num : nums_new) {
    std::cout << ' ' << num;
}
std::cout << std::endl;

return 0;

}
输出结果如下:

nums_ori contains: 10 20 20 20 30 30 20 20 10
nums_new contains: 10 20 30 20 10
自定义比较函数可以使用上面的lambda表达式,也可以如下定义:

bool myfunction (int i, int j) {
return (i==j);
}

作者:book_02
链接:https://www.jianshu.com/p/98eed6e85fd5
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。