【问题标题】:Remove overlap from vectors of vectors从向量的向量中删除重叠
【发布时间】:2011-06-07 00:11:36
【问题描述】:

基本上我正在做的是集合覆盖问题,从具有相同数字的向量中删除重复项。一个例子:

排序后我有以下向量向量:

{{1,2,3,4,5},{2,3,7,8},{10,11,12}}

现在,我想从 2nd 向量中删除该事件 2,3 并再次排序...

 {{1,2,3,4,5},{10,11,12},{7,8}}

我已经实现了一些代码来对向量的向量进行排序,但是我在从大小较小的向量中删除出现时遇到问题?

排序函数:

sort(ROWS.begin(),ROWS.end(),VectorsSort());

感谢您的帮助。

【问题讨论】:

  • 请注意,告诉我们您使用了一些名为 VectorsSort 的函子而不向我们展示 VectorsSort 的实际实现,这根本没有用。

标签: c++ arrays vector


【解决方案1】:

把它拆开,拿走你需要的东西:

#include <algorithm>
#include <vector>

struct binary_search_pred
{
    typedef bool result_type;

    explicit binary_search_pred(std::vector<int> const& v) : v_(&v) { }

    bool operator ()(int const& i) const
    {
        return std::binary_search(v_->begin(), v_->end(), i);
    }

private:
    std::vector<int> const* v_;
};

struct size_comparison_desc
{
    typedef bool result_type;

    typedef std::vector<int> const& arg_t;
    bool operator ()(arg_t a, arg_t b) const
    {
        return b.size() < a.size();
    }
};

void set_cover(std::vector<std::vector<int> >& vec)
{
    typedef std::vector<std::vector<int> > vec_t;
    typedef vec_t::iterator iter_t;
    typedef vec_t::const_iterator citer_t;

    if (vec.empty() || vec.size() == 1)
        return;

    for (iter_t v = vec.begin() + 1, v_end = vec.end(); v != v_end; ++v)
        for (citer_t p = vec.begin(); p != v; ++p)
            v->erase(
                std::remove_if(v->begin(), v->end(), binary_search_pred(*p)),
                v->end()
            );
    std::sort(vec.begin(), vec.end(), size_comparison_desc());
}

(注意set_cover 要求包含的std::vector&lt;int&gt;s 给定必须已经排序。)


编辑#1:

根据现在已删除的 cmets 中的要求,围绕 std::map&lt;int, std::vector&lt;int&gt;&gt; 而不是 std::vector&lt;std::vector&lt;int&gt;&gt; 的版本(使用原始代码中的 binary_search_pred):

#include <algorithm>
#include <map>
#include <vector>

void set_cover(std::map<int, std::vector<int> >& m)
{
    typedef std::map<int, std::vector<int> > map_t;
    typedef map_t::iterator iter_t;
    typedef map_t::const_iterator citer_t;

    if (m.empty() || m.size() == 1)
        return;

    for (iter_t v = ++m.begin(), v_end = m.end(); v != v_end; ++v)
        for (citer_t p = m.begin(); p != v; ++p)
            v->second.erase(
                std::remove_if(
                    v->second.begin(),
                    v->second.end(),
                    binary_search_pred(p->second)
                ),
                v->second.end()
            );
}

请注意,这里的map 将始终按其键排序,而不是按所包含的vector 的大小(这似乎是您想要的)。也许您想要 std::vector&lt;std::pair&lt;int, std::vector&lt;int&gt;&gt;&gt; 代替?


编辑 #2:

根据现在已删除的 cmets 中的要求,围绕 std::vector&lt;std::pair&lt;int, std::vector&lt;int&gt;&gt;&gt; 而不是 std::map&lt;int, std::vector&lt;int&gt;&gt; 的版本(使用原始代码中的 binary_search_pred):

#include <algorithm>
#include <utility>
#include <vector>

struct size_comparison_desc
{
    typedef bool result_type;

    typedef std::pair<int, std::vector<int> > const& arg_t;
    bool operator ()(arg_t a, arg_t b) const
    {
        return b.second.size() < a.second.size();
    }
};

void set_cover(std::vector<std::pair<int, std::vector<int> > >& vec)
{
    typedef std::vector<std::pair<int, std::vector<int> > > vec_t;
    typedef vec_t::iterator iter_t;
    typedef vec_t::const_iterator citer_t;

    if (vec.empty() || vec.size() == 1)
        return;

    for (iter_t v = vec.begin() + 1, v_end = vec.end(); v != v_end; ++v)
        for (citer_t p = vec.begin(); p != v; ++p)
            v->second.erase(
                std::remove_if(
                    v->second.begin(),
                    v->second.end(),
                    binary_search_pred(p->second)
                ),
                v->second.end()
            );
    std::sort(vec.begin(), vec.end(), size_comparison_desc());
}

【讨论】:

  • @PAASTINO :更改算法以满足您的要求。这就是为什么我说“把它拆开,拿走你需要的东西”——这并不是一个 100% 完整的解决方案,它只是为了让你朝着正确的方向开始。
【解决方案2】:
  1. 您不需要定义向量排序谓词。 Vector 已经定义了一个基于std::lexicographical_compareoperator&lt;

  2. 这是你的意思吗?

std::for_each(rows.begin(), rows.end(), [](std::vector<int>& row) {
    row.erase(std::remove_if(row.begin(), row.end(), [](int number) -> bool {
        return (number == 2) || (number == 3);
    }), row.end());
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-29
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    相关资源
    最近更新 更多