倒排列表求交集算法 包括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;
}
时间: 2024-10-14 10:08:12

倒排列表求交集算法 包括baeza yates的交集算法的相关文章

倒排列表求交集算法汇总

http://bbs.sjtu.edu.cn/bbstcon,board,Algorithm,reid,1225812893.html 我总结了一下,归纳如下: 1.1 SvS and Swapping SvS Algorithm 1 Pseudo-code for SvS SvS(set, k) 1: Sort the sets by size (|set[0]| ≤ |set[1]| ≤ . . . ≤ |set[k]|). 2: Let the smallest set s[0] be t

这就是搜索引擎--读书笔记七--倒排列表压缩算法

倒排列表压缩算法 目前有很多种倒排列表算法可以选择,但是我们对评判算法的优劣需要定量指标.一般会考虑3个指标:压缩率.压缩速度以及解压速度. 压缩率是指数据压缩前和压缩后大小的比例,显然,压缩率越高,就越节约磁盘空间.而压缩速度是压缩单位量的数据所花的时间,但是压缩往往是在建立索引过程中进行的,这是一个后台进行的过程,不需要及时响应用户查询,即使速度慢一些也没有关系.所以普遍来说,压缩速度不是一个重要指标. 那么我们来看看解压速度.顾名思义,解压就是将压缩数据恢复到原始数据.这是一个实时响应过程

搜索引擎基础概念(3)—— 倒排列表

倒排列表 倒排列表用来记录有哪些文档包含了某个单词.一般在文档集合里会有很多文档包含某个单词,每个文档 会记录文档编号(DocID),单词在这个文档中出现的次数(TF)及单词在文档中哪些位置出现过等信息,这样与一个文档相关的信息被称做倒排索引项(Posting),包含这个单词的一 系列倒排索引项形成了列表结构,这就是某个单词对应的倒排列表.图 1-1 是倒排列表的示意图,在文档集合中出现过的所有单词及其对应的倒排列表组成了倒排索引. 图1-1 倒排列表示意图 在实际的搜索引擎系统中,并不存储倒排

倒排列表压缩算法汇总——分区Elias-Fano编码貌似是最牛叉的啊!

来看看倒排索引压缩.压缩是拿CPU换IO的最重要手段之一,不论索引是放在硬盘还是内存中.索引压缩的算法有几十种,跟文本压缩不同,索引压缩算法不仅仅需要考虑压缩率,更要考虑压缩和解压性能,否则会解压太慢而起不到CPU换IO的作用.早期的索引设计里,在尝试了几十种编码之后,基本都确定性采用差分编码+可变长字节编码.差分的目的在于让索引的文档ID尽可能小,因为压缩小的整数总是比大整数更有效.在索引构建算法中,有一类工作叫做"文档重排",目的就是通过对文档索引顺序的重新排列,使得索引posti

ES里设置索引中倒排列表仅仅存文档ID

index_options The index_options parameter controls what information is added to the inverted index, for search and highlighting purposes. It accepts the following settings: docs Only the doc number is indexed. Can answer the question Does this term e

Poseidon 系统是一个日志搜索平台——认证看链接ppt,本质是索引的倒排列表和原始日志数据都存在HDFS,而文档和倒排的元数据都在NOSQL里,同时针对单个filed都使用了独立索引,使用MR来索引和搜索

Poseidon 系统是一个日志搜索平台,可以在百万亿条.100PB 大小的日志数据中快速分析和检索.360 公司是一个安全公司,在追踪 APT(高级持续威胁)事件,经常需要在海量的历史日志数据中检索某些信息,例如某个恶意样本在某个时间段内的活动情况.在 Poseidon 系统出现之前,都是写 Map/Reduce 计算任务在 Hadoop 集群中做计算,一次任务所需的计算时间从数小时到数天不等,大大制约了 APT 事件的追踪效率.Poseidon 系统就是解决这个需求,能在数百万亿条规模的数据

GPU方法做倒排压缩和交集计算

之前一直想读这篇,今天读了一下,颇有收获: 1.对文档按相似term聚类之后,delta较小,可以提高压缩率(similarity graph) 1.GPU一般可以有几百个核,有shared memory和global memory,shared memory相当于寄存器的速度,global memory速度较慢 2.有序数组上的搜索算法除了binary search还有interplation search(插值搜索),平均复杂度是O(loglogn),但memory access是binar

信息检索导论学习笔记 -- 第二章:词项词典及倒排记录表

2.1.1 文档分析及编码转换:      文档处理第一步,是将文件或web服务器上的一系列二进制字节序列转换为字符序列.      在实际中,首先要判断出文档的编码方式(机器学习分类.启发式等方法),确定文档的类型(word?zip?)然后将字节序列转换成字符序列. 2.1.2 文档单位(document unit)的选择:      常见的,将某个目录下的每个文件都看成一个文档.      但有些情况并非如此,比如我们可能希望将邮件.附件(附件中的文件)分开.      对于一个长文档而言,

倒排表数据结构、通配符查询、拼写纠正详解

目录: Dictionary Data Structure  词典数据结构 Wild-Card Query  通配符查询 Spelling Correction  拼写纠正 搜索引擎里的dictionary data通常存储着这些信息: 索引词(term vocabulary). 文档频率(document frequency,即这个词在多少个文档里出现). 指向倒排表的指针(pointers to each postings list ). 那么,他是怎样的一个数据结构呢? 一种非常naive