• 倒排列表求交集算法 包括baeza yates的交集算法


    #ifndef __INTERSECT_HPP__
    #define __INTERSECT_HPP__
    
    #include "probe.hpp"
    
    namespace themas {
    
    /*
     * like stl's set_intersect
     */
    template<class InputIterator, class OutputIterator>
    void linear_intersect(InputIterator begin1, InputIterator end1,
                          InputIterator begin2, InputIterator end2,
                          OutputIterator out)
    {
      if ( (end2 - begin2) > (end1 - begin1) )
      {
        // why in the world would i do this?
        // hmmmmmmm.......... !
        std::swap(begin1, begin2);
        std::swap(end1, end2);
      }
      while (begin1 != end1 && begin2 != end2)
      {
        if (*begin1 < *begin2)
          ++begin1;
        else if (*begin2 < *begin1)
          ++begin2;
        else
        {
          *out++ = *begin1;
          ++begin1;
          ++begin2;
        }
      }
    }
    
    /*
     * this time with a comparator!
     */
    template<class InputIterator, class OutputIterator, class Comparator >
    void linear_intersect(InputIterator begin1, InputIterator end1,
                          InputIterator begin2, InputIterator end2,
                          OutputIterator out, Comparator cmp)
    {
      if ( (end2 - begin2) > (end1 - begin1) )
      {
        // why in the world would i do this?
        // hmmmmmmm.......... !
        std::swap(begin1, begin2);
        std::swap(end1, end2);
      }
      while (begin1 != end1 && begin2 != end2)
      {
        if (cmp( *begin1, *begin2 ) )
          ++begin1;
        else if ( cmp(*begin2, *begin1) )
          ++begin2;
        else
        {
          *out++ = *begin1;
          ++begin1;
          ++begin2;
        }
      }
    }
    
    /*
     * baeza_intersect
     */
    template< template <class, class> class Probe,
      class RandomAccessIterator, class OutputIterator>
    void baeza_intersect(RandomAccessIterator begin1, RandomAccessIterator end1,
                         RandomAccessIterator begin2, RandomAccessIterator end2,
                         OutputIterator out)
    {
      RandomAccessIterator probe1, probe2;
    
      if ( (end1 - begin1) < ( end2 - begin2 ) )
      {
        if ( begin1 == end1 )
          return;
        probe1 = begin1 + ( ( end1 - begin1 ) >> 1 );
        probe2 = lower_bound< Probe >( begin2, end2, *probe1 );
        baeza_intersect< Probe >(begin1, probe1, begin2, probe2, out); // intersect left
        if (! (probe2 == end2 || *probe1 < *probe2 ))
          *out++ = *probe2++;
        baeza_intersect< Probe >(++probe1, end1, probe2, end2, out); // intersect right
      }
      else
      {
        if ( begin2 == end2 )
          return;
        probe2 = begin2 + ( ( end2 - begin2 ) >> 1 );
        probe1 = lower_bound< Probe >( begin1, end1, *probe2 );
        baeza_intersect< Probe >(begin1, probe1, begin2, probe2, out); // intersect left
        if (! (probe1 == end1 || *probe2 < *probe1 ))
          *out++ = *probe1++;
        baeza_intersect< Probe >(probe1, end1, ++probe2, end2, out); // intersect right
      }
    }
    
    /*
     * with a comparator
     */
    template< template <class, class> class Probe,
      class RandomAccessIterator, class OutputIterator, class Comparator >
    void baeza_intersect(RandomAccessIterator begin1, RandomAccessIterator end1,
                         RandomAccessIterator begin2, RandomAccessIterator end2,
                         OutputIterator out, Comparator cmp)
    {
      RandomAccessIterator probe1, probe2;
    
      if ( (end1 - begin1) < ( end2 - begin2 ) )
      {
        if ( begin1 == end1 )
          return;
        probe1 = begin1 + ( ( end1 - begin1 ) >> 1 );
        probe2 = lower_bound< Probe >( begin2, end2, *probe1, cmp );
        baeza_intersect< Probe >(begin1, probe1, begin2, probe2, out, cmp); // intersect left
        if (! (probe2 == end2 || cmp( *probe1, *probe2 ) ))
          *out++ = *probe2++;
        baeza_intersect< Probe >(++probe1, end1, probe2, end2, out, cmp); // intersect right
      }
      else
      {
        if ( begin2 == end2 )
          return;
        probe2 = begin2 + ( ( end2 - begin2 ) >> 1 );
        probe1 = lower_bound< Probe >( begin1, end1, *probe2, cmp );
        baeza_intersect< Probe >(begin1, probe1, begin2, probe2, out, cmp); // intersect left
        if (! (probe1 == end1 || cmp( *probe2, *probe1 ) ))
          *out++ = *probe1++;
        baeza_intersect< Probe >(probe1, end1, ++probe2, end2, out, cmp); // intersect right
      }
    }
    
    } // themas
    
    #endif // __INTERSECT_HPP__

    转自:https://github.com/erikfrey/themas/blob/master/src/set_intersection/intersect.hpp

    #include <iostream>
    #include <vector>
    #include <set>
    #include <ctime>
    
    #include <boost/random/mersenne_twister.hpp>
    
    #include "intersect.hpp"
    
    using namespace themas;
    
    int main(int argc, char * argv[])
    {
      std::set<int> nums1, nums2;
      std::vector<int> result1, result2, result3;
    
      boost::mt19937 rng(time(NULL));
    
      for ( unsigned int i = rng() % 16384; i != 0; --i )
        nums1.insert(rng());
      for ( unsigned int i = rng() % 16384; i != 0; --i )
        nums2.insert(rng());
      for ( unsigned int i = rng() % 16384; i != 0; --i )
      {
        unsigned int j = rng();
        nums1.insert(j);
        nums2.insert(j);
      }
      std::vector<int> v1(nums1.begin(), nums1.end()), v2(nums2.begin(), nums2.end());
    
      linear_intersect(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(result1));
      baeza_intersect < binary_probe > (v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(result2));
      baeza_intersect < interpolation_probe > (v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(result3));
    
      if (result1 != result2 || result1 != result3)
        std::cout << "FAIL!" << std::endl;
      else
        std::cout << "PASS!" << std::endl;
    }
  • 相关阅读:
    德才真值表
    Linaro公司基于GCC推出的的ARM交叉编译工具
    荣耀4CROOT 成功!附本人ROOT过程——KINGROOT
    batman-adv——B.A.T.M.A.N. Advanced quick start guide
    linux内核外部驱动模块编译报错ERROR—drivers/*.ko] undefined
    Linux Kernel and Driver Development Training——linux-kernel-slides
    华为手机——解锁步骤
    编译Linux内核—浅谈EABI和OABI
    Linux Kernel and Driver Development Training
    Android—Step by step
  • 原文地址:https://www.cnblogs.com/bonelee/p/6594263.html
Copyright © 2020-2023  润新知