[C++ MAP]map多key值查找问题

chinaljj 2009-10-14 10:38:19
请高人多多指教...

1 一个map,两个key值,初始状态下两个key都有值。
2 key1与key2取值没有交集。
3 key1取值没有重复;key2取值没有重复。
4 查找时给一个值(a),事先知道(a)是key1类型的值还是key2类型的值。
如果(a)是key1类型的值,则map中用(a)与key1做匹配进行查找;
如果(a)是key2类型的值,则map中用(a)与key2做匹配进行查找;
5 会有给一个值(a)匹配到一个key1后,要同时得到key2的值的情况出现。

代码如下:
#include <iostream>
#include <string>
#include <map>

using namespace std;

//========================================================
typedef struct tagUKey
{
char a[10]; // 如果给定一个值,在map中有一个a与之匹配,则还要返回b的值。
char b[20];

bool operator <(const struct tagUKey&ths) const
{
// 这里如何实现???
return (((strcmp(a,ths.a)<0)||((strcmp(a,ths.a)>0)&& (strcmp(b,ths.b)<0)))&& (strcmp(b,ths.b)<0));
}

} UKey;

map<UKey, int> gDat;
typedef map<UKey, int>::iterator Dat_It;
typedef map<UKey, int>::value_type Dat_Val;

//========================================================
// 初始化map
void init()
{
UKey s;
strcpy(s.a,"11");
strcpy(s.b,"4111");
gDat.insert(Dat_Val(s,1));

strcpy(s.a,"22");
strcpy(s.b,"4222");
gDat.insert(Dat_Val(s,2));

strcpy(s.a,"33");
strcpy(s.b,"4333");
gDat.insert(Dat_Val(s,3));

strcpy(s.a,"44");
strcpy(s.b,"4444");
gDat.insert(Dat_Val(s,4));

strcpy(s.a,"55");
strcpy(s.b,"4555");
gDat.insert(Dat_Val(s,5));
}

//========================================================
// 根据key值查找
int findKey(int nFlag,char *pInfo,char *pOut)
{
UKey s;
switch(nFlag)
{
case 0: // 给定的值是要与key1匹配的
strcpy(s.a,pInfo);
break;
case 1: // 给定的值是要与key2匹配的
strcpy(s.b,pInfo);
break;
}

Dat_It tmpIt;
tmpIt = gDat.find(s);
if (tmpIt != gDat.end())
{
printf("find. dat=%d\n",tmpIt->second);
switch(nFlag)
{
case 0: // 找到匹配的key1,还要通过参数带出key2的值。
strcpy(pOut,tmpIt->first.b);
return tmpIt->second;
case 1: // 找到匹配的key2,还要通过参数带出key1的值。
strcpy(pOut,tmpIt->first.a);
return tmpIt->second;
}
}
else
printf("not find.\n");

return 0;
}

//========================================================
int main(int argc, char **argv)
{
init();

char szOut[20] = {0};
int ret = 0;
ret = findKey(0,"11",szOut);
if (ret)
printf("ret=%d,out=%s\n",ret,szOut);

ret = findKey(1,"4111",szOut);
if (ret)
printf("ret=%d,out=%s\n",ret,szOut);

ret = findKey(0,"22",szOut);
if (ret)
printf("ret=%d,out=%s\n",ret,szOut);

ret = findKey(1,"4555",szOut);
if (ret)
printf("ret=%d,out=%s\n",ret,szOut);

return 0;
}

/*-------------------------------------------------------------
输出为:

not find. // 这里很奇怪,没找到。如何实现重载<,才好?
find. dat=1
ret=1,out=11
find. dat=2
ret=2,out=4222
find. dat=5
ret=5,out=55

-------------------------------------------------------------*/

助人为乐.....先谢谢了...
...全文
1645 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
miky_sun 2009-11-27
  • 打赏
  • 举报
回复
你的想法很好啊,给了我不少启示,我给你的代码修改了下,就可以正常查询到了!
bool operator< (const struct tagUKey& key) const
{
// 这里如何实现???
if (strlen(key.a) > 0)
{
return strcmp(a, key.a);
}
if (strlen(key.b) > 0)
{
return strcmp(b, key.b);
}
//return ( ((strcmp(a,ths.a) <0)||((strcmp(a,ths.a)>0)&& (strcmp(b,ths.b) <0)))
// && (strcmp(b,ths.b) <0) );
}
cphj 2009-10-14
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 chinaljj 的回复:]
领教领教。
还想请教下:find_if 与map自带的find相比较,效率方面有差异吗?我这里map中的数据量很大,效率要求比较高。
[/Quote]

map自带的效率高,它的复杂度是O(logN)
通用的是O(N)

但是map自带的find不能带自定义比较函数,它会调T类型的operator==()成员
taodm 2009-10-14
  • 打赏
  • 举报
回复
楼主啊,你这个场合根本不该用map的。
找本《effective stl》认真系统学一下stl的一些基本使用吧。
chinaljj 2009-10-14
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 cphj 的回复:]
用find_if()来查找,然后定义2个不同的全局比较函数

bool cmp1(const UKey & , const UKey &);
里面判断a是否相等

bool cmp2(const UKey & , const UKey &);
里面判断b是否相等

找到之后,再用返回的it读取值
[/Quote]

领教领教。
还想请教下:find_if 与map自带的find相比较,效率方面有差异吗?我这里map中的数据量很大,效率要求比较高。
cphj 2009-10-14
  • 打赏
  • 举报
回复
至于为什么operator<()不工作的原因,1楼说了

因为find和find_if是线性查找,它们只需要满足input_iterator概念(concepts)的叠代器就行了
而input_iterator叠代器,只需要operator==(),并不需要也不会去调用operator<()
cphj 2009-10-14
  • 打赏
  • 举报
回复
用find_if()来查找,然后定义2个不同的全局比较函数

bool cmp1(const UKey & , const UKey &);
里面判断a是否相等

bool cmp2(const UKey & , const UKey &);
里面判断b是否相等

找到之后,再用返回的it读取值
macrojj 2009-10-14
  • 打赏
  • 举报
回复
bool operator <(const struct tagUKey&ths) const
{
// 这里如何实现???
return (((strcmp(a,ths.a) <0)||((strcmp(a,ths.a)>0)&& (strcmp(b,ths.b) <0)))&& (strcmp(b,ths.b) <0));
}


你应该重载 < 还是==?
chinaljj 2009-10-14
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 cphj 的回复:]
引用 4 楼 chinaljj 的回复:
领教领教。
还想请教下:find_if 与map自带的find相比较,效率方面有差异吗?我这里map中的数据量很大,效率要求比较高。


map自带的效率高,它的复杂度是O(logN)
通用的是O(N)

但是map自带的find不能带自定义比较函数,它会调T类型的operator==()成员

[/Quote]

感谢“cphj”的热心,感谢给我的支持,十分感谢!
由于效率方面的考虑,看来这个map的构建需要考虑用变通的方法实现了,费些周折。

结贴!再次感谢回帖的各位...
chinaljj 2009-10-14
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 taodm 的回复:]
楼主啊,你这个场合根本不该用map的。
找本《effective stl》认真系统学一下stl的一些基本使用吧。
[/Quote]

噢,看来你学过stl。那你说说我这场合该用什么?!“高人”?
有能耐就说,没能耐就闭嘴。废话真多...

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧