删除两个向量中的重复项
Removing duplicates in two vectors
I'll try to explain my problem with the following example:
vector<pair<string, string>> a = { { "A","1" }, {"B","2" },{ "C","3" },{ "D","3" },{ "E","5" } };
vector<pair<string, string>> b = { { "A","1" },{ "B","3" },{ "D","3" },{ "E","4" },{ "Z","5" } };
删除重复项并将输出放入相同向量的最有效方法是什么?对的数量非常大,可以说大约 100 000。
两个向量都按第一个元素排序。
vector<pair<string, string>> a = { { "B","2" },{ "C","3" },{ "E","5" } };
vector<pair<string, string>> b = { { "B","3" },{ "E","4" },{ "Z","5" } };
问题是,我需要在删除重复项后比较这些向量。
该对中的第一个元素是文件路径,第二个是它的校验和。
因此,例如,如果我在第一个容器中有 "B","2"
,而第二个容器中有 "B","3"
,我可以将此文件列为 "modified"。我愿意使用 std::set
如果这会使这个问题更容易。
您可以使用 STL 库中的一些算法来帮助解决此任务。首先找到相同的元素并将它们放入临时向量中,然后从每个向量中删除这些元素,请参见代码示例:
vector<pair<string, string>> a = { { "A","1" }, {"B","2" },{ "C","3" },{ "D","3" },{ "E","5" } };
vector<pair<string, string>> b = { { "A","1" },{ "B","3" },{ "D","3" },{ "E","4" },{ "Z","5" } };
//Vector to hold same elements
vector<pair<string, string>> same_elements {};
//Fill same_elements vector
std::for_each(a.begin(), a.end(), [&same_elements, b]( pair<string, string>& el )
{
if( find(b.begin(), b.end(), el) != b.end() )
{
same_elements.push_back(el);
}
});
//Remove same elements from a and b
std::for_each(same_elements.begin(), same_elements.end(), [&a, &b]( pair<string, string>& el_to_delete )
{
auto It_a = find(a.begin(), a.end(), el_to_delete);
if( It_a != a.end() )
{
a.erase(It_a);
}
auto It_b = find(b.begin(), b.end(), el_to_delete);
if( It_b != b.end() )
{
b.erase(It_b);
}
});
我使用 std::for_each
遍历向量的每个元素,std::find
在向量中查找所需的元素,erase
使用向量方法通过迭代器从向量中删除相同的元素。
使用 运行 索引将为您提供 O(len(a) + len(b)) 时间复杂度和 O(1) 额外 space(给定 a
和 b
已经排序)
void removeDuplicate(vector<pair<string, string>>& a, vector<pair<string, string>>& b) {
//Add these two lines if there can be duplicates in a or b themselves.
//a.erase(std::unique(a.begin(), a.end()), a.end());
//b.erase(std::unique(b.begin(), b.end()), b.end());
size_t i = 0;
size_t j = 0;
size_t p1 = 0;
size_t p2 = 0;
while(i < a.size() && j < b.size()) {
if(a[i] == b[j]) {
i++;
j++;
} else if (a[i] > b[j]) {
b[p2++] = b[j++];
} else if (b[j] > a[i]) {
a[p1++] = a[i++];
}
}
while(i < a.size()) {
a[p1++] = a[i++];
}
while(j < b.size()) {
b[p2++] = b[j++];
}
a.erase(a.begin()+p1, a.end());
b.erase(b.begin()+p2, b.end());
}
我认为任何标准库算法都不会在这里直接提供帮助。
我们首先检查是否应该删除(从两者中删除),否则我们将指向较小值的迭代器前进并继续。
for (auto ait = a.begin(), bit = b.begin(); ait != a.end() && bit != b.end();)
{
if (*ait == *bit)
{
// Potenitally multiple duplicate values
ait = a.erase(std::remove(ait, a.end(), *ait), a.end());
bit = b.erase(std::remove(bit, b.end(), *bit), b.end());
}
else if (*ait < *bit) ++ait;
else ++bit;
}
I'll try to explain my problem with the following example:
vector<pair<string, string>> a = { { "A","1" }, {"B","2" },{ "C","3" },{ "D","3" },{ "E","5" } };
vector<pair<string, string>> b = { { "A","1" },{ "B","3" },{ "D","3" },{ "E","4" },{ "Z","5" } };
删除重复项并将输出放入相同向量的最有效方法是什么?对的数量非常大,可以说大约 100 000。
两个向量都按第一个元素排序。
vector<pair<string, string>> a = { { "B","2" },{ "C","3" },{ "E","5" } };
vector<pair<string, string>> b = { { "B","3" },{ "E","4" },{ "Z","5" } };
问题是,我需要在删除重复项后比较这些向量。
该对中的第一个元素是文件路径,第二个是它的校验和。
因此,例如,如果我在第一个容器中有 "B","2"
,而第二个容器中有 "B","3"
,我可以将此文件列为 "modified"。我愿意使用 std::set
如果这会使这个问题更容易。
您可以使用 STL 库中的一些算法来帮助解决此任务。首先找到相同的元素并将它们放入临时向量中,然后从每个向量中删除这些元素,请参见代码示例:
vector<pair<string, string>> a = { { "A","1" }, {"B","2" },{ "C","3" },{ "D","3" },{ "E","5" } };
vector<pair<string, string>> b = { { "A","1" },{ "B","3" },{ "D","3" },{ "E","4" },{ "Z","5" } };
//Vector to hold same elements
vector<pair<string, string>> same_elements {};
//Fill same_elements vector
std::for_each(a.begin(), a.end(), [&same_elements, b]( pair<string, string>& el )
{
if( find(b.begin(), b.end(), el) != b.end() )
{
same_elements.push_back(el);
}
});
//Remove same elements from a and b
std::for_each(same_elements.begin(), same_elements.end(), [&a, &b]( pair<string, string>& el_to_delete )
{
auto It_a = find(a.begin(), a.end(), el_to_delete);
if( It_a != a.end() )
{
a.erase(It_a);
}
auto It_b = find(b.begin(), b.end(), el_to_delete);
if( It_b != b.end() )
{
b.erase(It_b);
}
});
我使用 std::for_each
遍历向量的每个元素,std::find
在向量中查找所需的元素,erase
使用向量方法通过迭代器从向量中删除相同的元素。
使用 运行 索引将为您提供 O(len(a) + len(b)) 时间复杂度和 O(1) 额外 space(给定 a
和 b
已经排序)
void removeDuplicate(vector<pair<string, string>>& a, vector<pair<string, string>>& b) {
//Add these two lines if there can be duplicates in a or b themselves.
//a.erase(std::unique(a.begin(), a.end()), a.end());
//b.erase(std::unique(b.begin(), b.end()), b.end());
size_t i = 0;
size_t j = 0;
size_t p1 = 0;
size_t p2 = 0;
while(i < a.size() && j < b.size()) {
if(a[i] == b[j]) {
i++;
j++;
} else if (a[i] > b[j]) {
b[p2++] = b[j++];
} else if (b[j] > a[i]) {
a[p1++] = a[i++];
}
}
while(i < a.size()) {
a[p1++] = a[i++];
}
while(j < b.size()) {
b[p2++] = b[j++];
}
a.erase(a.begin()+p1, a.end());
b.erase(b.begin()+p2, b.end());
}
我认为任何标准库算法都不会在这里直接提供帮助。
我们首先检查是否应该删除(从两者中删除),否则我们将指向较小值的迭代器前进并继续。
for (auto ait = a.begin(), bit = b.begin(); ait != a.end() && bit != b.end();)
{
if (*ait == *bit)
{
// Potenitally multiple duplicate values
ait = a.erase(std::remove(ait, a.end(), *ait), a.end());
bit = b.erase(std::remove(bit, b.end(), *bit), b.end());
}
else if (*ait < *bit) ++ait;
else ++bit;
}