Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 类似于'std::set_intersection',但生成成对的相等元素_C++_C++11 - Fatal编程技术网

C++ 类似于'std::set_intersection',但生成成对的相等元素

C++ 类似于'std::set_intersection',但生成成对的相等元素,c++,c++11,C++,C++11,我得到了两个按某些标准排序的容器,例如,按ID号排序的人 我希望通过相同的标准找到两个容器共有的所有元素,并且我希望访问两个被认为相等的元素 我考虑执行合并,然后手动扫描相等的相邻元素。但也许有一个更优雅的算法 struct Employee { int id; int salary; Employee(int id, int salary); }; struct ById { bool operator()(const Employee& left

我得到了两个按某些标准排序的容器,例如,按ID号排序的人

我希望通过相同的标准找到两个容器共有的所有元素,并且我希望访问两个被认为相等的元素

我考虑执行合并,然后手动扫描相等的相邻元素。但也许有一个更优雅的算法

struct Employee
{
    int id;
    int salary;

    Employee(int id, int salary);
};

struct ById 
{
    bool operator()(const Employee& left, const Employee& right) {
        return left.id < right.id;
    }
};

std::vector<Employee> first = { Employee(10, 1000), 
                                Employee(12, 1000), 
                                Employee(31, 10000) }; // Note: sorted by Id
std::vector<Employee> second = { Employee(1, 1500), 
                                 Employee(10, 2000), 
                                 Employee(31, 12000) }; // Note: sorted by Id

// prints the following:
//  [id: 10, salary: 1000], [id: 10, salary: 2000]    // id 10 exists in both containers
//  [id: 31, salary: 10000], [id: 31, salary: 12000]  // id 31 exists in both containers
MySetIntersection( // <--- I WANT TO KNOW HOW TO IMPLEMENT THIS
    begin(first), end(first),
    begin(second), end(second),
    ById(),
    [] (const Person& left, const Person& right) { 
        std::cout << "[" << left << "], [" << right << "]" std::endl; 
    }
);

到目前为止你试过什么?这似乎是一个相当简单的算法:

template<typename ForwardIterator1, typename ForwardIterator2, typename Func>
  void for_each_intersecting(ForwardIterator1 begin1, ForwardIterator1 end1, ForwardIterator2 begin2, ForwardIterator2 end2, Func what) {
      while( (begin1 != end1) && (begin2 != end2) ) {
          if( *begin1 < *begin2 )
            ++begin1;
          else if( *begin2 < *begin1 )
            ++begin2;
          else
            what(*begin1++, *begin2++);
      }
  }
但请注意,这可能会比原始答案慢,占用更多内存

或者,如果没有lambdas:

#include <iostream>
#include <algorithm>
#include <functional>

struct employee {
    int id, salary;
    bool operator<(const employee& e) { return id < e.id; }
    bool operator==(const employee& e) { return id == e.id; }
};

int main() {
    std::vector<employee> v1 { { 1, 1500 }, { 10, 2000 }, { 15, 2500 }, { 16, 1000 } };
    std::vector<employee> v2 { { 10, 1500 }, { 13, 2000 }, { 15, 500 }, { 19, 1300 } };
    std::vector<employee> v3; v3.reserve(v1.size()+v2.size());
    std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(v3));
    for( auto a = v3.begin(), e = v3.end(); (a = std::adjacent_find(a, e)) != e; ++a ) {
      std::cout << a->id << ' ' << a->salary << ' ';
      ++a;
      std::cout << a->id << ' ' << a->salary << '\n';
    }
}

看起来马萨在我测试的时候打败了我,但无论如何我都会用比较函数来展示它

template<typename InputIt1, typename InputIt2, typename Compare, typename Func>
void MySetIntersection(InputIt1 first1, InputIt1 last1,
    InputIt2 first2, InputIt2 last2,
    Compare comp, Func func)
{
    while (first1 != last1 && first2 != last2) {
        if (comp(*first1, *first2))
            ++first1;
        else if (comp(*first2, *first1))
            ++first2;
        else
            func(*first1++, *first2++);
    }
}

看起来像是手动实现了一个合并。我以为有更优雅的东西。。。就像一个STL的一个班轮。当然,最后一行不是应该是func*first1++、*first2++?是的,我在最后一分钟重新安排了事情,制造了一个bug。我看到你详细阐述了你的答案,所以很遗憾我的答案被接受了+给你的。
template<typename InputIt1, typename InputIt2, typename Compare, typename Func>
void MySetIntersection(InputIt1 first1, InputIt1 last1,
    InputIt2 first2, InputIt2 last2,
    Compare comp, Func func)
{
    while (first1 != last1 && first2 != last2) {
        if (comp(*first1, *first2))
            ++first1;
        else if (comp(*first2, *first1))
            ++first2;
        else
            func(*first1++, *first2++);
    }
}