std::vector 比较两个vector是否相等
目录
std::vector 比较两个vector是否相等
1. 利用std::vector的operator==函数
1.1 示例代码
#include <vector>
#include <iostream>
int main()
{
std::vector<int> vector1, vector2;
for (int i = 1; i < 10; ++i)
{
vector1.push_back(i);
vector2.push_back(i);
}
// 直接比较
if (vector1 == vector2)
{
std::cout << "vector1 == vector2" << std::endl;
}
else
{
std::cout << "vector1 != vector2" << std::endl;
}
return 0;
}
/* run output:
vector1 == vector2
*/
1.2 解析源码
1.2.1 源码
// std::vector类的operator==重载函数
template <class _Ty, class _Alloc>
_NODISCARD bool operator==(const vector<_Ty, _Alloc>& _Left, const vector<_Ty, _Alloc>& _Right) {
return _Left.size() == _Right.size()
&& _STD equal(_Left._Unchecked_begin(), _Left._Unchecked_end(), _Right._Unchecked_begin());
}
// std::equal
template <class _InIt1, class _InIt2, class _Pr>
_NODISCARD _CONSTEXPR20 bool equal(const _InIt1 _First1, const _InIt1 _Last1, const _InIt2 _First2, _Pr _Pred) {
// compare [_First1, _Last1) to [_First2, ...) using _Pred
_Adl_verify_range(_First1, _Last1);
auto _UFirst1 = _Get_unwrapped(_First1);
const auto _ULast1 = _Get_unwrapped(_Last1);
auto _UFirst2 = _Get_unwrapped_n(_First2, _Idl_distance<_InIt1>(_UFirst1, _ULast1));
if constexpr (decltype(_Equal_memcmp_is_safe(_UFirst1, _UFirst2, _Pred))::value) {
#ifdef __cpp_lib_is_constant_evaluated
if (!_STD is_constant_evaluated())
#endif // __cpp_lib_is_constant_evaluated
{
const auto _First1_ch = reinterpret_cast<const char*>(_UFirst1);
const auto _First2_ch = reinterpret_cast<const char*>(_UFirst2);
const auto _Count = static_cast<size_t>(reinterpret_cast<const char*>(_ULast1) - _First1_ch);
return _CSTD memcmp(_First1_ch, _First2_ch, _Count) == 0;
}
}
for (; _UFirst1 != _ULast1; ++_UFirst1, (void) ++_UFirst2) {
if (!_Pred(*_UFirst1, *_UFirst2)) {
return false;
}
}
return true;
}
1.2.2 解析
可以看到,首先判断两个vector的大小是否相等,如果大小不等,则视为不相同;
如果大小相等,再调用std::equal函数来进行判断。
而equal函数,实现核心:
for (; _UFirst1 != _ULast1; ++_UFirst1, (void) ++_UFirst2) {
if (!_Pred(*_UFirst1, *_UFirst2)) {
return false;
}
}
上面的UFirst1以及ULast1都是第一个vector的起始和终止迭代器;
UFirst2是第二个vector的起始迭代器,代码主要比较两个vector相同位置上的值相同即可。
1.3 应用注意事项(存在问题)
1.3.1 示例代码
#include <vector>
#include <iostream>
int main()
{
int a = 100;
int b = 200;
std::vector<int*> vector1;
vector1.push_back(&a);
vector1.push_back(&b);
std::vector<int*> vector2;
vector2.push_back(&b);
vector2.push_back(&a);
if (vector1 == vector2)
{
std::cout << "vector1 == vector2" << std::endl;
}
else
{
std::cout << "vector1 != vector2" << std::endl;
}
return 0;
}
/* run output:
vector1 != vector2
*/
1.3.2 存在问题
如上示例,很明显,本期望是两个vector相同,但是经过比较后,却判定为不相同。事与愿违。
问题根因:没有对容器vector的元素排序,std::equal函数只是对比两个容器对称索引处两个数据值是否相同。
应用注意事项:如果应用时,两个容器的元素可能顺序不相同,建议优先对容器元素进行排序。
优化后,示例代码:
#include <vector>
#include <iostream>
#include <algorithm>
int main()
{
int a = 100;
int b = 200;
std::vector<int*> vector1;
vector1.push_back(&a);
vector1.push_back(&b);
std::vector<int*> vector2;
vector2.push_back(&b);
vector2.push_back(&a);
// 利用算法先排序
std::sort(vector1.begin(), vector1.end());
std::sort(vector2.begin(), vector2.end());
if (vector1 == vector2)
{
std::cout << "vector1 == vector2" << std::endl;
}
else
{
std::cout << "vector1 != vector2" << std::endl;
}
return 0;
}
/* run output:
vector1 == vector2
*/
2. 自定义方法
2.1 仿标准库写法
2.1.1 示例代码
#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
bool compareVector(std::vector<int*> vector1, std::vector<int*> vector2)
{
if (vector1.size() != vector2.size())
{
return false;
}
std::sort(vector1.begin(), vector1.end());
std::sort(vector2.begin(), vector2.end());
auto iter1 = vector1.begin();
auto iter2 = vector2.begin();
while (iter1 != vector1.end() && iter2 != vector2.end() && (*iter1) == (*iter2))
{
++iter1;
++iter2;
}
if (iter1 == vector1.end())
{
return true;
}
return false;
}
int main()
{
int a = 100, b = 200, c = 300;
std::vector<int*> vector1;
vector1.push_back(&a);
vector1.push_back(&b);
vector1.push_back(&c);
std::vector<int*> vector2;
vector2.push_back(&b);
vector2.push_back(&c);
vector2.push_back(&a);
if (compareVector(vector1, vector2))
{
std::cout << "vector1 == vector2" << std::endl;
}
else
{
std::cout << "vector1 != vector2" << std::endl;
}
return 0;
}
/* run output:
vector1 == vector2
*/
2.1.2 解析
仿标准库的思路,只是自定义多增加了排序的步骤。
2.2 利用std::set容器元素的唯一性
2.2.1 示例代码
#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
bool compareVector(std::vector<int*> vector1, std::vector<int*> vector2)
{
if (vector1.size() != vector2.size())
{
return false;
}
// 利用std::set元素唯一性特征
std::set<int*> tempSet(vector1.begin(), vector1.end());
for (const auto& item2 : vector2)
{
if (tempSet.insert(item2).second)
{
return false; // 但凡有一个数据插入成功,则视为不相同
}
}
return true;
}
int main()
{
int a = 100, b = 200, c = 300;
std::vector<int*> vector1;
vector1.push_back(&a);
vector1.push_back(&b);
vector1.push_back(&c);
std::vector<int*> vector2;
vector2.push_back(&b);
vector2.push_back(&c);
vector2.push_back(&a);
if (compareVector(vector1, vector2))
{
std::cout << "vector1 == vector2" << std::endl;
}
else
{
std::cout << "vector1 != vector2" << std::endl;
}
return 0;
}
/* run output:
vector1 == vector2
*/
2.2.2 解析
主要思路:利用std::set容器的唯一性特性。
实现方法:利用一个临时std::set,构造时将vector1所有元素填充进去。
如果vector2容器但凡有一个元素插入成功,说明vector2容器中发现有元素与vector1不同,则可判定两个容器不相同。