[英]Best way for key comparison (C++ map)
使用地圖時,有時在定義比較函數以使用自己的數據類型插入地圖時有時會遇到一些問題。 例如,目前我具有這樣的結構:
typedef struct triple_key{
int int_key;
struct some_data;
unsigned char char_array_key[16];
}triple_key;
其中some_data是這樣的:
struct some_data{
int data_length;
unsigned char* data;
}
為了進行比較,我覆蓋了operator(),我的想法是執行以下操作:
class comp_triple_key{
public:
bool operator()(const triple_key &x, const triple_key &y){
if(x.int_key!= y.int_key){
return x.int_key<y.int_key;
}
else{
if(memcmp((x.some_data).data, (y.some_data).data, (x.some_data).data_length) != 0){
return memcmp((x.some_data).data, (y.some_data).data, (x.some_data).data_length) < 0;
}
else{
return memcmp((x.char_array_key), (y.char_array_key), 16*sizeof(char))<0;
}
}
};
};
然后,地圖將如下所示:
std::map<triple_key,int,comp_triple_key> my_map;
有沒有更好的方法來比較這多個鍵值? 在大多數情況下,這可行(並且可以正常工作),但有時我會斷言:
Expression: invalid operator <
過去,我已經解決了這個問題,但是我不清楚如何總體上避免這種問題,或者哪種常見的處理此類問題的方法可以確保它在每種情況下都有效。
有幾件事情要做:
operator<
像這樣的作品:
bool operator<(const triple_key &x, const triple_key &y){
if(x.int_key!= y.int_key){
return x.int_key<y.int_key;
}
else{
if(memcmp((x.somedata).data, (y.somedata).data, (x.somedata).data_length) != 0){
return memcmp((x.somedata).data, (y.somedata).data, (x.somedata).data_length) < 0;
}
else{
return memcmp((x.char_array_key), (y.char_array_key), 16*sizeof(char))<0;
}
}
}
那么您可以創建如下對象:
std::map<triple_key,int> my_map;
可編譯的示例(問題中的固定代碼):
#include <map>
#include <iostream>
#include <string>
#include <string.h>
struct some_data{
int data_length;
unsigned char* data;
};
struct triple_key{
int int_key;
some_data somedata ;
unsigned char char_array_key[16];
};
bool operator<(const some_data &x, const some_data &y){
if(x.int_key!= y.int_key){
return x.int_key<y.int_key;
}
else{
if(memcmp((x.somedata).data, (y.somedata).data, (x.somedata).data_length) != 0){
return memcmp((x.somedata).data, (y.somedata).data, (x.somedata).data_length) < 0;
}
else{
return memcmp((x.char_array_key), (y.char_array_key), 16*sizeof(char))<0;
}
}
}
bool operator<(const triple_key &x, const triple_key &y){
if(x.int_key!= y.int_key){
return x.int_key<y.int_key;
}
else{
if(memcmp((x.somedata).data, (y.somedata).data, (x.somedata).data_length) != 0){
return memcmp((x.somedata).data, (y.somedata).data, (x.somedata).data_length) < 0;
}
else{
return memcmp((x.char_array_key), (y.char_array_key), 16*sizeof(char))<0;
}
}
}
int main()
{
std::map<triple_key,int> my_map;
}
越簡單越好。 只需將這個方案一一比較:
bool operator()(const triple_key &x, const triple_key &y){
if (x.int_key < y.int_key)
return true;
if (y.int_key < x.int_key)
return false;
if (lexicographical_compare(x.some_data.data, x.some_data.data + x.some_data.data_length,
y.some_data.data, y.some_data.data + y.some_data.data_length))
return true;
if (lexicographical_compare(y.some_data.data, y.some_data.data + y.some_data.data_length,
x.some_data.data, x.some_data.data + x.some_data.data_length))
return false;
return memcmp(x.char_array_key, y.char_array_key, sizeof(y.char_array_key)) < 0;
}
#include <iostream>
#include <memory>
#include <map>
using namespace std;
struct some_data{
int data_length;
unsigned char* data;
bool operator < (const some_data& other) const
{
if (memcpy(data, other.data, data_length) < 0)
return true;
else
return false;
}
};
typedef struct triple_key{
int int_key;
struct some_data data;
unsigned char uuid[16];
bool operator < (const triple_key& other) const
{
if (int_key < other.int_key)
return true;
else
{
if (data < other.data)
return true;
else
{
if (memcpy((void*)uuid, (void*)other.uuid, sizeof(uuid)) < 0)
return true;
}
}
return false;
}
}triple_key;
int main()
{
some_data data1;
data1.data = (unsigned char *)malloc(4);
data1.data_length = 4;
some_data data2;
data2.data = (unsigned char *)malloc(5);
data2.data_length = sizeof(5);
triple_key key1;
key1.int_key = 1;
key1.data = data1;
triple_key key2;
key2.int_key = 2;
key2.data = data2;
std::map<triple_key, int> myMap;
myMap[key1] = 1;
myMap[key2] = 2;
cout<<myMap.size()<<endl;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.