我正在尝试实施Google Dense Hash。这是我第一次使用C ++来处理比使用整数的简单向量更复杂的东西,所以我找不到问题,即使我觉得它应该很简单。
我粘贴了以下相关代码。
header.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"
//Debugger
#define DEBUG false
#define STATES false
#define MANUAL false
//Setting up the randomness
typedef boost::mt19937 RandomNumberGenerator;
typedef boost::uniform_int<> NumberDistribution;
typedef boost::variate_generator<RandomNumberGenerator&, NumberDistribution> Generator;
static RandomNumberGenerator generator;
#endif
traverse-markov.cc:
//Include the header
#include "header.h"
int main (int argc, char* argv[]) {
//Default values of Controlvariables
int initial_conditions = 100000; // Number of initial states to generate.
int repeat_per_condition = 1; // Default number of initial states to generate.
int iterations = 2000; // Number of steps to run.
int seed = 1234; // Random seed to generate conditions
bool synchronous = true;
bool random_order = false;
bool silent = false;
bool false_feedback = false;
bool same_states = false;
int decay_counter = 0;
int update_method = 0;
std::string input_filename;
std::string output_filename;
std::string initial_condition_file;
Markovgraph markov;
markov.add_vertex("a");
markov.add_vertex("a");
markov.add_vertex("b");
markov.add_vertex("c");
markov.vertices_status();
std::cout << "Number of vertices: " << markov.vertex_count() << std::endl;
return 0;
}
markovgraph.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));
}
};
typedef google::dense_hash_map<const char*, long int, MurmurHasher<const char*>, eqstr> dense_hash_t;
class Markovgraph {
//Private variables
dense_hash_t 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);
void print_vertex(std::string vertex);
void vertices_status();
int vertex_count();
//add_edge(std::string upvertex,std::string downvertex);
~Markovgraph(); //Destructor
};
#endif
markovgraph.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() {
vertices.set_empty_key(NULL);
//edges.set_empty_key(NULL);
}
//Add vertex function
void Markovgraph::add_vertex(std::string vertex) {
vertices[vertex.c_str()] = 1;
}
//Print vertex function
void Markovgraph::print_vertex(std::string vertex) {
std::cout << vertex << " --> " << vertices[vertex.c_str()] << std::endl;
}
//Print all vertices
void Markovgraph::vertices_status() {
// Print whole hash table to cout
for(dense_hash_t::const_iterator it = vertices.begin(); it != vertices.end(); it++){
std::cout << it->first << " --> " << it->second << std::endl;
}
}
//Vertex count
int Markovgraph::vertex_count() {
return vertices.size();
}
//Destructor
Markovgraph::~Markovgraph() {
//Destroy things...
}
输出结果为:
c --> 1
Number of vertices: 1
所以不知何故只保存了最后一个“顶点”。我尝试使用markov.add_vertex()添加的早期键/值对消失了。
我希望你能帮助我,因为我已经待了一个多星期。
答案 0 :(得分:0)
void Markovgraph::add_vertex(std::string vertex) {
vertices[vertex.c_str()] = 1;
}
将导致指向保存add_vertex
的本地字符串的指针,一旦离开该函数,vertex
将不再存在,因此使用指针将是UB。
解决此问题的最简单方法可能是让您的密钥为std::string