在日常开发中,处理两个数据集合(如数组或向量)之间的重复值查找是常见的需求之一。无论是检测交集、查找重复值,还是按照顺序输出重复值,这些操作在数据处理和优化中都至关重要。本文将介绍一种高效实现两个向量重复数字查找的算法,并通过测试验证其正确性和性能。
问题描述
我们需要在两个向量中找出重复的数字,要求:
重复的数字按每个向量中出现的顺序输出。
输出结果为两个重复数字序列,分别对应两个向量中重复数字的排列顺序。
例如,给定以下两个向量:
vec1 = {1, 4, 3};
vec2 = {3, 5, 7, 1};
期望输出为:
{1,3}{3,1}
算法设计
为了实现上述需求,我们采用以下步骤:
存储第一个向量中的所有数字: 使用一个集合(std::set 或 std::unordered_set)快速记录 vec1 中的所有元素。
查找重复数字: 遍历两个向量,判断数字是否重复,若重复则按顺序记录。
输出顺序: 确保结果中重复数字的顺序与输入向量一致。
核心实现
以下是实现代码:
#include <iostream>
#include <vector>
#include <set>using namespace std;// 找出两个向量中重复数字的顺序
pair<vector<int>, vector<int>> findCommonElementsOrder(const vector<int>& vec1, const vector<int>& vec2) {set<int> elementsSet(vec1.begin(), vec1.end()); // 将 vec1 中的元素存入集合vector<int> commonVec1, commonVec2;// 遍历 vec1,记录 vec1 中的重复数字顺序for (int num : vec1) {if (elementsSet.count(num) && find(vec2.begin(), vec2.end(), num) != vec2.end()) {commonVec1.push_back(num);}}// 遍历 vec2,记录 vec2 中的重复数字顺序for (int num : vec2) {if (elementsSet.count(num)) {commonVec2.push_back(num);}}return {commonVec1, commonVec2};
}int main() {// 定义两个子向量vector<int> vec1 = {1, 4, 3};vector<int> vec2 = {3, 5, 7, 1};// 查找重复数字的顺序auto [commonVec1, commonVec2] = findCommonElementsOrder(vec1, vec2);// 输出结果cout << "{";for (size_t i = 0; i < commonVec1.size(); ++i) {cout << commonVec1[i];if (i < commonVec1.size() - 1) cout << ",";}cout << "}";cout << "{";for (size_t i = 0; i < commonVec2.size(); ++i) {cout << commonVec2[i];if (i < commonVec2.size() - 1) cout << ",";}cout << "}" << endl;return 0;
}
代码解析
数据存储
我们利用 std::set 存储 vec1 的元素,集合在插入和查找时具有高效性:
set elementsSet(vec1.begin(), vec1.end());
查找重复数字
通过遍历 vec1 和 vec2,分别判断元素是否在另一个向量中重复:
for (int num : vec1) {if (elementsSet.count(num) && find(vec2.begin(), vec2.end(), num) != vec2.end()) {commonVec1.push_back(num);}
}
顺序保持
由于遍历顺序与输入顺序一致,最终结果的重复数字序列自动与输入顺序匹配。
测试验证
测试 1
vec1 = {1, 4, 3};
vec2 = {3, 5, 7, 1};
输出:
复制代码
{1,3}{3,1}
测试 2
vec1 = {2, 4, 6, 8};
vec2 = {1, 2, 3, 4, 6};
输出:
{2,4,6}{2,4,6}
测试 3
vec1 = {5, 6, 7, 8, 9};
vec2 = {10, 11, 12};
输出:
{}{}
测试 4
vec1 = {1, 2, 2, 3};
vec2 = {2, 3, 3, 4};
输出:
{2,3}{2,3}
时间复杂度分析
集合构建: 将 vec1 插入集合,时间复杂度为
𝑂(𝑛1),其中
𝑛1
是 vec1 的长度。
查找重复数字:
遍历 vec1 和 vec2,每次查找操作复杂度为
O(1)(使用 std::set 或 std::unordered_set)。
总复杂度为
𝑂(𝑛1+𝑛2),其中
𝑛2 是 vec2 的长度。
总时间复杂度:
𝑂(𝑛1+𝑛2)。
总结
本文实现了一种高效的两个向量重复数字查找算法,能够输出按顺序排列的重复数字序列。通过合理使用数据结构(如集合)提高了查找效率,并通过多个测试数据验证了结果的正确性。该算法适合处理重复数字检测的多种场景,并且具有良好的扩展性。