我需要实现一个C ++类来支持以下
数据:
key - string
subkey - string / double
值 - 字符串/双
key& subkey一起唯一标识该行。
例如:
[ "key", "subkey", "value" ]
[ "cse", "a", 100 ]
[ "cse", "b", 120 ]
[ "cse", 100, 10 ]
操作:
1)给出一个关键&返回值
2)给定一个键返回一个[ "subkey", "value" ]
我面临的问题是subkey和value可以是double和string。 解决此问题的一种方法是使用一个包装类,它能够存储double和string类型。
第一级地图将以字符串作为键,值将为地图。
第二级映射将使用键作为新的包装类,值也是一个新的包装类。
这种方法对吗?或者有更好的方法吗?
答案 0 :(得分:2)
我使用Boost.Variant和C ++ 11 unordered_map
破解了一个解决方案。代码是C ++ 11实际应用的一个很好的例子。
你需要特别注意两个哈希的组合
在std::hash<key>::operator()
的专业化中,它可以有一个
对哈希质量的强烈影响。为了更好的实施
看看boost::hash_combine
,遗憾的是没有
标准化。
一般来说代码的作用是:定义一个特殊的键类型
EqualityComparable和Hashable,然后在它中使用它
std::unordered_map
。你可以用Boost和no来构建所有这些
完全是C ++ 11。如果你既没有Boost也没有C ++ 11,那么你就处于紧张状态
点。没有对此进行真正的测试。
#include <boost/variant.hpp>
#include <string>
#include <functional>
#include <unordered_map>
#include <iostream>
struct key {
std::string primary;
boost::variant<std::string, double> secondary;
friend bool operator==(const key& x, const key& y)
{ return x.primary == y.primary && x.secondary == y.secondary; }
};
namespace std {
template<>
struct hash<key> {
std::size_t operator()(const key& k) const
{
std::size_t first = std::hash<std::string>()(k.primary);
std::size_t second;
// check for the more likely case first
if(const std::string* s = boost::get<std::string>(&(k.secondary))) {
second = std::hash<std::string>()(*s);
} else {
const double* d = boost::get<double>(&(k.secondary));
second = std::hash<double>()(*d);
}
return first ^ ( second << 1 ); // not so fancy hash_combine
}
};
} // std
int main()
{
typedef std::unordered_map<key, boost::variant<std::string, double>> MyMap;
MyMap m = {
{{"foo", "bar"}, "foobar"},
{{"foo", 23.0}, "foo23"},
{{"nothing", 23.0}, 23.0}
};
std::cout << m[{"foo", "bar"}] << std::endl;
std::cout << m[{"foo", 23.0}] << std::endl;
std::cout << m[{"nothing", 23.0}] << std::endl;
return 0;
}
答案 1 :(得分:1)
以下每个键浪费一点空间,但具有简单的优点:
struct Key
{
Key(string primary, string subkey)
: primary(primary)
, is_double(false)
, string_subkey(subkey)
{}
Key(string primary, double subkey)
: primary(primary)
, is_double(true)
, double_subkey(subkey)
{}
string primary;
bool is_double;
double double_subkey;
string string_subkey;
}
您需要实施适当的比较操作和/或哈希函数。