【问题标题】:How to get original positions of items in an intersection?如何获取交叉点中项目的原始位置?
【发布时间】:2021-12-14 08:44:39
【问题描述】:

我有两个包含整数的向量,我可以得到这些向量的交集,但这只会给我值,我还想知道原始项目的索引位置/键。我怎样才能做到这一点?我尝试使用lower_bound 在每个向量中搜索交叉点中的项目以找到它们的位置,但这很慢。我希望有一些聪明的方法可以在set_intersection 中使用自定义比较器或类似的东西来访问被比较的每个项目的键,但是我没有任何运气来寻找一种方法来做到这一点.

【问题讨论】:

  • 您应该展示如何获得交点的值。获得索引可能只需要很少的修改。
  • 用索引 + 值制作一个结构并制作它的向量。编写自己的算法来返回这些索引,有很多方法可以做到。
  • 也许您应该考虑编写自己的类似set_intersection 的函数,它返回一组索引对?
  • set_intersection 适用于排序序列...您的向量是否已排序?它们是否包含唯一整数?
  • 这两个向量的大小是否相同?它们是完全随机的吗?

标签: c++ intersection


【解决方案1】:

正确答案是Some programmer dude。好主意。

我在 cppreference.com C++ 文档中找到了 set_intersection 实现。我按照他的建议做了一些修改,效果很好。

下面是展示其工作原理的示例代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

using namespace std;

template<class Value, class InputIt1, class InputIt2, class OutputIt>
OutputIt my_intersection(InputIt1 first1, InputIt1 last1,
                         InputIt2 first2, InputIt2 last2,
                         OutputIt d_first)
{
    auto start1 = first1;
    auto start2 = first2;

    while (first1 != last1 && first2 != last2) {
        if (*first1 < *first2) {
            first1++;
            continue;
        }

        if (*first2 == *first1) {
            pair<Value, vector<size_t>> item;
            vector<size_t> positions;

            positions.push_back (distance (start1, first1));
            positions.push_back (distance (start2, first2));

            item.first = *first1;
            item.second = positions;

            *d_first++ = item;

            *first1++;
        }

        first2++;
    }

    return d_first;
}

int main()
{
    vector<int> v1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    vector<int> v2 = { 2, 4, 6, 8, 30, 50, 70, 90, 100, 1000 };

    vector<pair<int, vector<size_t>>> intersection;

    my_intersection<int> (
        v1.begin (), v1.end (),
        v2.begin (), v2.end (),
        back_inserter (intersection)
    );

    for (auto &item : intersection) {
        cout << item.first << ":";

        for (auto &position : item.second) {
            cout << " " << position;
        }

        cout << endl;
    }
}

输出:

2: 1 0
4: 3 1
6: 5 2
8: 7 3

【讨论】:

  • 这是一个小风格的东西,但我可以建议 if (*first1 &lt; *first2) { ++first1; continue; } 然后将该循环体的其余部分移出 else 子句,删除一个缩进级别?
  • 这是有道理的。完成了。
猜你喜欢
  • 2015-07-13
  • 1970-01-01
  • 1970-01-01
  • 2017-01-28
  • 2015-05-18
  • 2021-03-23
  • 2019-02-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多