c++ - 如何在 C++ 中集成 Google 稀疏哈希

标签 c++ hash header-files

对于一个研究项目,我正在研究计算机模型。到目前为止,我对 c++ 不是很了解,因为它完成的任务不是很复杂。但是我现在需要一个快速哈希表,所以我正在尝试集成 Google 稀疏哈希。经过两天修改头文件后,我被卡住了。

不知何故,一旦我的对象的构造函数完成,整个哈希表就会被清空。我希望你能帮助我修复以下代码。我排除了所有我确定不相关的代码,但如果我需要添加更多,请告诉我。

生成文件:

# Object files:
OBJ = traverse-markov.o gene.o genome.o markovgraph.o
# Header files:
HDR = gene.h header.h genome.h markovgraph.h
# Libraries that we need to link to:
#LIBS = -lGL -lX11 -lm
# One rule to invoke what we need:
all : traverse-markov
# C++ 'compile' command:
CPP = g++ -ggdb3
LINK= g++
# Generic rules
%.o : %.cc ${HDRS}
    ${CPP} -o $@ -I ~/lib/ -c $<
# The final step:
traverse-markov : ${OBJ}
    ${LINK} -o $@ ${LIBS} ${OBJ}
clean:
    rm -rf *.o traverse-markov

标题.h:

#ifndef HEADER_H
#define HEADER_H

//#include <stdint.h>
#include <iostream>
#include <vector>
#include <ctime>
#include <fstream>
#include <boost/random.hpp>
#include <sparsehash/dense_hash_map>

#include "gene.h"
#include "genome.h"
#include "markovgraph.h"

//Setting up the randomness
typedef boost::mt19937 RandomNumberGenerator;
typedef boost::uniform_int<> NumberDistribution;
typedef boost::variate_generator<RandomNumberGenerator&, NumberDistribution> Generator;

static RandomNumberGenerator generator;

#endif

遍历-markov.cc:

#include "header.h"
int main (int argc, char* argv[]) {
  Markovgraph markov;
  markov.add_vertex("a");
  return 0;
}

马尔可夫图.h:

#ifndef MARKOVGRAPH_H
#define MARKOVGRAPH_H

extern uint64_t MurmurHash64A ( const void * key, int len, unsigned int seed );

// simple hash adapter for types without pointers
template<typename T>
struct MurmurHasher {
    size_t operator()(const T& t) const {
        return MurmurHash64A(&t, sizeof(t), 0);
    }    
};

// specialization for strings
template<>
struct MurmurHasher<std::string> {
    size_t operator()(const std::string& t) const {
        return MurmurHash64A(t.c_str(), t.size(), 0);
    }    
};

struct eqstr
{
  bool operator()(const char* s1, const char* s2) const
  {
    return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0);
  }
};

class Markovgraph {
    //Private variables
  google::dense_hash_map<const char*, long, MurmurHasher<const char*>, eqstr> vertices;
  google::dense_hash_map<const char*, long, MurmurHasher<const char*>, eqstr> edges;

    public:
        //Public variables

        //Functions
        Markovgraph(); //Constructor
    void add_vertex(std::string vertex);
    //add_edge(std::string upvertex,std::string downvertex);
    ~Markovgraph(); //Destructor
};

#endif

马尔可夫图.cc:

//Include the header
#include "header.h"

// 64-bit hash for 64-bit platforms
// copied from https://sites.google.com/site/murmurhash/
uint64_t MurmurHash64A ( const void * key, int len, unsigned int seed ) {
  const uint64_t m = 0xc6a4a7935bd1e995;
  const int r = 47;

  uint64_t h = seed ^ (len * m);

  const uint64_t * data = (const uint64_t *)key;
  const uint64_t * end = data + (len/8);

  while(data != end)
  {
    uint64_t k = *data++;

    k *= m; 
    k ^= k >> r; 
    k *= m; 

    h ^= k;
    h *= m; 
  }

  const unsigned char * data2 = (const unsigned char*)data;

  switch(len & 7)
  {
  case 7: h ^= uint64_t(data2[6]) << 48;
  case 6: h ^= uint64_t(data2[5]) << 40;
  case 5: h ^= uint64_t(data2[4]) << 32;
  case 4: h ^= uint64_t(data2[3]) << 24;
  case 3: h ^= uint64_t(data2[2]) << 16;
  case 2: h ^= uint64_t(data2[1]) << 8;
  case 1: h ^= uint64_t(data2[0]);
          h *= m;
  };

  h ^= h >> r;
  h *= m;
  h ^= h >> r;

  return h;
} 

//Constructor
Markovgraph::Markovgraph() {
    google::dense_hash_map<const char*, long, MurmurHasher<const char*>, eqstr> vertices;
    vertices.set_empty_key(NULL);

    google::dense_hash_map<const char*, long, MurmurHasher<const char*>, eqstr> edges;
    edges.set_empty_key(NULL);

    vertices["a"] = 10000;
    vertices["b"] = 573;
    std::cout << vertices["a"] << std::endl;
    std::cout << vertices["b"] << std::endl;
    std::cout << vertices.size() << std::endl;
}

//Add vertex function
void Markovgraph::add_vertex(std::string vertex) {
    std::cout << vertices.size() << std::endl;

}

//Destructor
Markovgraph::~Markovgraph() {
    //Destroy things...
}

现在这个输出:

10000
573
2
0

所以前三个数字 a 符合我的预期。但是一旦 Markovgraph::add_vertex 函数被调用(或构造函数完成后),整个顶点哈希再次为空。

编辑

好的,从构造函数中删除变量 edges 和 vertices 就可以了。但是现在出了点问题:

//Constructor
Markovgraph::Markovgraph() {
    vertices.set_empty_key(NULL);
    edges.set_empty_key(NULL);
}

//Add vertex function
void Markovgraph::add_vertex(std::string vertex) {
  vertices[vertex] = 1;
  std::cout << vertices[vertex] << std::endl;
}

编译时出现如下错误: markovgraph.cc:58: 错误:“((Markovgraph*)this)->Markovgraph::vertices[vertextoadd]”中的“operator[]”不匹配

最佳答案

verticesedges 是构造函数中的局部变量,隐藏同名的实例变量。要将实例变量初始化为空哈希表,只需从构造函数中删除这些变量:

Markovgraph::Markovgraph() {
    // note: no declarations of vertices and edges here
    vertices.set_empty_key(NULL);
    edges.set_empty_key(NULL);

    vertices["a"] = 10000;
    vertices["b"] = 573;
    std::cout << vertices["a"] << std::endl;
    std::cout << vertices["b"] << std::endl;
    std::cout << vertices.size() << std::endl;
}

这是有效的,因为构造函数隐式调用了实例变量的默认构造函数。

关于c++ - 如何在 C++ 中集成 Google 稀疏哈希,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19297918/

相关文章:

javascript - 编辑 window.location.hash 将导致删除查询字符串

c - C 库的公共(public)头文件是否应该#include 其他带有双引号或尖括号的头文件?

c++ - 在 Visual Studio Code 中为 C++ 创建一个新类?

c++ - GetPrivateProfileString 的目的是什么?

c++ - pthread_create() 是如何工作的?

c++ - 用于 ASCII 的环绕式 C++

cryptography - SHA-1 密码存储安全吗?

c++ - 通过其成员的地址激活嵌套 union 是否合法?

用于登录密码的 PHP 盐和哈希 SHA256

c++ - 为什么要在 C++ 程序中创建 abc.h 和 abc.cpp 文件?