字典容器,在键不完全正确时也可以查找值 我需要一个C++内存字典容器,它得到一个密钥,并以任何方式返回一个值。 也就是说,如果键在“键列表”中不存在,它将找到最相似的键,并给出值
有什么建议吗 编辑: 谢谢你的评论 更多详情:字典容器,在键不完全正确时也可以查找值 我需要一个C++内存字典容器,它得到一个密钥,并以任何方式返回一个值。 也就是说,如果键在“键列表”中不存在,它将找到最相似的键,并给出值,c++,dictionary,containers,C++,Dictionary,Containers,有什么建议吗 编辑: 谢谢你的评论 更多详情: 为了简单起见,让我们从数字键开始。如果钥匙与钥匙的距离在200以内,则取下它 解决这个问题的一种方法可能是编写自己的容器类,通过组合扩展std::map 持有一个std::map作为成员,并转发所需的函数和typedef 确保您的“试错”逻辑至少具有以下功能: 计数 查找 操作员[] at 您需要使用一个名为的东西,并且您需要在它上面写一点代码(我保证只写一点点,多写一个字) 首先,您需要使用std::map而不是std::unordered_m
为了简单起见,让我们从数字键开始。如果钥匙与钥匙的距离在200以内,则取下它 解决这个问题的一种方法可能是编写自己的容器类,通过组合扩展
std::map
持有一个std::map
作为成员,并转发所需的函数和typedef
确保您的“试错”逻辑至少具有以下功能:
计数
查找
操作员[]
at
- 您需要使用一个名为的东西,并且您需要在它上面写一点代码(我保证只写一点点,多写一个字)
首先,您需要使用
std::map
而不是std::unordered_map
或任何其他哈希表-它必须是树或其他有序数据结构
您的密钥将是对位置敏感的散列,它具有散列相似输入以关闭输出的行为。因此AAA和AAB的哈希比AAA和CCC的哈希更接近。值将是您想要的任何值
要检索“最近的匹配”,只需使用std::map::lower_bound
(或std::map::upper_bound
)从映射中获取与任何给定输入最近的值
所以你的代码看起来像这样
std::map<unsigned int, some_struct> mymap;
for(;;;)
{
mymap[locale_sensitive_hash(some_struct(some random value))] = some_struct(some random value)
}
//Now find the object we have that is nearest to some_struct(AAA)
unsigned int this_hash = locale_sensitive_hash(some_struct(AAA));
some_struct nearest_object = mymap.lower_bound(this_hash);
std::map mymap;
对于(;;)
{
mymap[locale\u sensitive\u hash(一些\u结构(一些随机值))]=一些\u结构(一些随机值)
}
//现在找到离某个结构(AAA)最近的对象
unsigned int this_hash=locale_sensitive_hash(some_struct(AAA));
最近的某个\u结构\u对象=mymap.lower\u bound(此\u散列);
做了,做了
一些注意事项:
这是假设一个非数字键。数字本身已经是“区域敏感哈希”,即如果H(n)
是n
,那么H(n)
和H(n')
之间的差异与输入n
和n'
之间的差异成正比。在这种情况下,lower_bound
是您唯一需要的,您不需要额外的散列步骤
您可以非常轻松地扩展此方法,以执行诸如指定对象之间的最大距离之类的操作。这将取决于您正在使用的区域设置敏感哈希以及它如何表示两个给定输入的两个哈希之间的距离,但通常只需在返回
最近的结构之前比较H(n)
和H(n')
(其中最近的结构为n'
).一种方法是使用多重映射
T& get(int key)
{
// use a multimap as storage
static multimap<int, T> m;
multimap<int, T>::iterator best;
// search for key within 200
for (auto it = m.lower_bound(key-200); it != m.upper_bound(key+200); ++it)
if (best)
// if multiple matches use the closest one to the key
best = (abs(it->first-key) < abs(best->first-key) ? it : best);
else
best = it;
// if none found, insert new entry
if (!best)
best = m.insert(key, T());
return best->second;
}
T&get(int键)
{
//使用多重映射作为存储
静态多重映射;
多重映射::迭代器最佳;
//在200以内搜索密钥
用于(自动it=m.下限(键-200);it!=m.上限(键+200);+it)
如果(最好)
//如果有多个匹配项,请使用与键最近的匹配项
最佳=(abs(it->first key)first key)?it:best;
其他的
最佳=它;
//如果未找到,请插入新条目
如果(!最好)
best=m.insert(键,T());
返回最佳->第二;
}
另一种更快但更混乱的方法是使用无序的_图和两级键
T& get(int key)
{
struct KeyValue
{
int key;
T value;
};
static unordered_map<int, vector<KeyValue>> m;
vector<KeyValue>::iterator best;
int b = key/200;
int a = b - 1;
int c = b + 1;
// function to search bucket for a key...
auto ms = [&](int bucket)
{
for (auto it = m[bucket].begin(); it != m[bucket].end(); ++it)
if (abs(it->key - key) <= 200)
{
if (best)
best = (abs(it->key - key) < abs(best->key - key));
else
best = it;
}
};
ms(a);
ms(b);
ms(c);
if (!best)
best = m[key/200].push_back({key, T()});
return best->value;
}
T&get(int键)
{
结构键值
{
int键;
T值;
};
静态无序映射m;
向量::迭代器最佳;
int b=键/200;
INTA=b-1;
int c=b+1;
//用于搜索存储桶中的密钥的函数。。。
自动ms=[&](整数桶)
{
对于(自动it=m[bucket].begin();it!=m[bucket].end();++it)
如果(abs(it->key-key)key-key)key-key));
其他的
最佳=它;
}
};
ms(a);
ms(b);
ms(c);
如果(!最好)
best=m[key/200]。向后推({key,T()});
返回最佳->值;
}
您必须自己处理“如果密钥不存在,则查找最相似的密钥”逻辑。在标准库(或者我所知道的任何地方)中没有一个结构可以为你做到这一点。最相似的键是什么?通常,我们假设一个键是唯一的,并且与某个值相关联。除非你说的是多重映射等。如果键不存在,你想让你的特殊容器做一些尝试和错误吗?(比如在字符串中交换大小写等),或者你想让多个键映射到映射中的同一个值。@Dave和其他人,所以,我需要自己写一个方法,好吗。我想我需要排序列表中的所有键,不是吗?如何做到这一点?您不一定需要对键进行排序。这取决于你的最佳匹配标准。这是他需要做的,但相似性本身又如何呢?根据对象的类型,这可能会简单得多。