【问题标题】:c++ STL set differencec++ STL设置区别
【发布时间】:2010-09-21 23:44:51
【问题描述】:

C++ STL 集合数据结构有集合差分算子吗?

【问题讨论】:

    标签: c++ stl set stdset set-difference


    【解决方案1】:

    是的,它在<algorithm> 中,被称为:std::set_difference。用法是:

    #include <algorithm>
    #include <set>
    #include <iterator>
    // ...
    std::set<int> s1, s2;
    // Fill in s1 and s2 with values
    std::set<int> result;
    std::set_difference(s1.begin(), s1.end(), s2.begin(), s2.end(),
        std::inserter(result, result.end()));
    

    最后,集合result 将包含s1-s2

    【讨论】:

    • +1。可悲的是,当我需要它时,我放弃了并滚动了自己的循环:(
    • 顺便说一句,如果您在非关联容器类(例如向量)上使用 set_difference,请确保首先对两个容器中的元素进行排序...
    • #include -> 没有这样的文件,应该是 ?
    • for set 我必须限定 std::insert_iterator>(...)
    • 文档说set_difference 要求对两个容器进行排序。 set 真的排序了吗?不明显。
    【解决方案2】:

    是的,算法头中有一个set_difference 函数。

    编辑:

    仅供参考,集合数据结构能够有效地使用该算法,如其documentation 所述。该算法不仅适用于集合,还适用于排序集合上的任何一对迭代器。

    正如其他人所提到的,这是一种外部算法,而不是一种方法。大概这对您的应用程序来说很好。

    【讨论】:

    • 它可用于任何对已排序的容器。
    【解决方案3】:

    不是语言意义上的“算子”,但标准库中有set_difference算法:

    http://www.cplusplus.com/reference/algorithm/set_difference.html

    当然,其他基本集合操作也存在 - (联合等),正如链接文章末尾的“另见”部分所建议的那样。

    【讨论】:

      【解决方案4】:

      C++ 没有定义集合差分运算符,但您可以定义自己的(使用其他响应中给出的代码):

      template<class T>
      set<T> operator -(set<T> reference, set<T> items_to_remove)
      {
          set<T> result;
          std::set_difference(
              reference.begin(), reference.end(),
              items_to_remove.begin(), items_to_remove.end(),
              std::inserter(result, result.end()));
          return result;
      }
      

      【讨论】:

        【解决方案5】:

        选择的答案是正确的,但有一些语法错误。

        代替

        #include <algorithms>
        

        使用

        #include <algorithm>
        

        代替

        std::insert_iterator(result, result.end()));
        

        使用

        std::insert_iterator<set<int> >(result, result.end()));
        

        【讨论】:

        • 或者直接使用std::inserter(result, result.end())
        【解决方案6】:

        再次为救援加油:

        #include <string>
        #include <set>
        #include <boost/range/algorithm/set_algorithm.hpp>
        
        std::set<std::string> set0, set1, setDifference;
        boost::set_difference(set0, set1, std::inserter(setDifference, setDifference.begin());
        

        setDifference 将包含 set0-set1。

        【讨论】:

          【解决方案7】:

          不是作为方法而是有外部算法函数set_difference

          template <class InputIterator1, class InputIterator2, class OutputIterator>
          OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
                                        InputIterator2 first2, InputIterator2 last2,
                                        OutputIterator result);
          

          http://www.sgi.com/tech/stl/set_difference.html

          【讨论】:

            【解决方案8】:

            显然,确实如此。

            SGI - set_difference

            【讨论】:

              【解决方案9】:

              我在这里看到的所有答案都是 O(n)。这不是更好吗?:

              template <class Key, class Compare, class Allocator>   
              std::set<Key, Compare, Allocator> 
              set_subtract(std::set<Key, Compare, Allocator>&& lhs,
                           const std::set<Key, Compare, Allocator>& rhs) {
                  if (lhs.empty()) { return lhs; }
                  // First narrow down the overlapping range:
                  const auto rhsbeg = rhs.lower_bound(*lhs.begin());
                  const auto rhsend = rhs.upper_bound(*lhs.rbegin());
                  for (auto i = rhsbeg; i != rhsend; ++i) {
                      lhs.erase(*i);
                  }
                  return std::move(lhs);
              }
              

              这似乎是对的。我不确定如何处理Compare 的类型没有完全指定其行为的情况,就像Comparestd::function&lt;bool(int,int)&gt;,但除此之外,这似乎工作正常并且应该就像 O((num 重叠) • log(lhs.size()))。

              lhs 不包含*i 的情况下,可能可以通过O(log(rhs.size())) 搜索rhs 的下一个元素来进一步优化,即>= 下一个lhs 的元素。这将优化lhs = {0, 1000}rhs = {1, 2, ..., 999} 在日志时间内进行减法的情况。

              【讨论】:

                【解决方案10】:

                我们可以用吗

                 set_difference(set1.begin(), set1.end(), set2.begin(). set2,end(),std::back_inserter(result)).
                

                【讨论】:

                • std::back_inserter 需要目标容器result 上的push_back() 方法。如果resultstd::set,这将不起作用
                • 请不要在答案中提出问题。
                猜你喜欢
                • 1970-01-01
                • 2013-01-13
                • 1970-01-01
                • 2011-07-09
                • 1970-01-01
                • 2012-10-08
                • 2011-01-31
                • 1970-01-01
                相关资源
                最近更新 更多