s****a 发帖数: 238 | 1 我的程序里需要用到一个std::map的对象,其中l_set是我定义的一个类型
,为了能作为map的key为这个类型定义了<算符。但是后来发现有些情况下明明确定这
个map已经正确初始化了,其中有某个key,但是取出的值总是0,但大多数时候运行有
是正常的。
后来我遍历了这个map,发现它有两次遇到这个key,第一次对应的value是正确的,第
二次就变成0了,但显然在map不可能有两个同样的key。我觉得我的<应该没有问题(非
常简单),对map得实现由不是很清楚,所以现在束手无策,对stl比较熟的能不能给点
线索。 |
N***m 发帖数: 4460 | 2 你自己定义的l_set是如何比较大小的?
【在 s****a 的大作中提到】 : 我的程序里需要用到一个std::map的对象,其中l_set是我定义的一个类型 : ,为了能作为map的key为这个类型定义了<算符。但是后来发现有些情况下明明确定这 : 个map已经正确初始化了,其中有某个key,但是取出的值总是0,但大多数时候运行有 : 是正常的。 : 后来我遍历了这个map,发现它有两次遇到这个key,第一次对应的value是正确的,第 : 二次就变成0了,但显然在map不可能有两个同样的key。我觉得我的<应该没有问题(非 : 常简单),对map得实现由不是很清楚,所以现在束手无策,对stl比较熟的能不能给点 : 线索。
|
d****p 发帖数: 685 | 3 Make sure when using operator [], the key does exist otherwise it will
insert a new value (probably initialized with 0) with the key.
So use map.find(key) != map.end() to check whether the key exists first
before retrieving the value.
STL map is based on redblack tree.
【在 s****a 的大作中提到】 : 我的程序里需要用到一个std::map的对象,其中l_set是我定义的一个类型 : ,为了能作为map的key为这个类型定义了<算符。但是后来发现有些情况下明明确定这 : 个map已经正确初始化了,其中有某个key,但是取出的值总是0,但大多数时候运行有 : 是正常的。 : 后来我遍历了这个map,发现它有两次遇到这个key,第一次对应的value是正确的,第 : 二次就变成0了,但显然在map不可能有两个同样的key。我觉得我的<应该没有问题(非 : 常简单),对map得实现由不是很清楚,所以现在束手无策,对stl比较熟的能不能给点 : 线索。
|
a****o 发帖数: 686 | |
s****a 发帖数: 238 | 5 l_set就是三个整数,我把<的定义也贴上来了,应该很简单
struct l_set {int l1;int l2;int l3;};
inline bool operator < (const l_set set1, const l_set set2))
{
if (set1.l1
return true;
else if (set1.l1==set2.l1 && set1.l2
return true;
else if (set1.l2==set2.l2 && set1.l3
return true;
else
return false; //when set1==set2 return false, as required by |
l******e 发帖数: 12192 | 6 第二个else if,如果set1.l1>set2.l1, set1.l2=set2.l2, set1.l3
【在 s****a 的大作中提到】 : l_set就是三个整数,我把<的定义也贴上来了,应该很简单 : struct l_set {int l1;int l2;int l3;}; : inline bool operator < (const l_set set1, const l_set set2)) : { : if (set1.l1: return true; : else if (set1.l1==set2.l1 && set1.l2: return true; : else if (set1.l2==set2.l2 && set1.l3: return true;
|
a****o 发帖数: 686 | 7 你怎么两次遍历的?中间有没有对iterator的操作?插入删去节点的操作?
贴代码吧。
【在 s****a 的大作中提到】 : l_set就是三个整数,我把<的定义也贴上来了,应该很简单 : struct l_set {int l1;int l2;int l3;}; : inline bool operator < (const l_set set1, const l_set set2)) : { : if (set1.l1: return true; : else if (set1.l1==set2.l1 && set1.l2: return true; : else if (set1.l2==set2.l2 && set1.l3: return true;
|
d****p 发帖数: 685 | 8 His comparator is right - it is a strict weak ordering.
【在 l******e 的大作中提到】 : 第二个else if,如果set1.l1>set2.l1, set1.l2=set2.l2, set1.l3
|
l******e 发帖数: 12192 | 9 错了吧
l1是tms,l3是tls,他的第二个else if就错了
【在 d****p 的大作中提到】 : His comparator is right - it is a strict weak ordering.
|
a****o 发帖数: 686 | 10 what is tms? tls?
currently, i agree with decamp, as long as it is operator <, doesn't matter how the human logic works.
【在 l******e 的大作中提到】 : 错了吧 : l1是tms,l3是tls,他的第二个else if就错了
|
|
|
s****a 发帖数: 238 | 11 你是对的,太谢谢了,第二个else if 应该是
else if (set1.l1==set2.l1 && set1.l2==set2.l2 && set1.l3
然后就对了,是我思路不清楚,浪费了整整一天...
【在 l******e 的大作中提到】 : 错了吧 : l1是tms,l3是tls,他的第二个else if就错了
|
a****o 发帖数: 686 | 12 a good point to learn.
【在 s****a 的大作中提到】 : 你是对的,太谢谢了,第二个else if 应该是 : else if (set1.l1==set2.l1 && set1.l2==set2.l2 && set1.l3: 然后就对了,是我思路不清楚,浪费了整整一天...
|
l******e 发帖数: 12192 | 13 the most significant, the least significant
比较错误的话,楼主就可能有的keys在map里被当成一个key了;但是楼主其他的code就
不这么认为了。
matter how the human logic works.
【在 a****o 的大作中提到】 : what is tms? tls? : currently, i agree with decamp, as long as it is operator <, doesn't matter how the human logic works.
|
s****a 发帖数: 238 | 14 理论上确实不影响,但是我定义的比较算附对于相同的对象会得出true的结果,那就是
错了,执行起来就一片混乱
matter how the human logic works.
【在 a****o 的大作中提到】 : what is tms? tls? : currently, i agree with decamp, as long as it is operator <, doesn't matter how the human logic works.
|
a****o 发帖数: 686 | 15 听君一席话,胜读十年书。
你居然还能判断楼主的心意,太厉害了,这合理推断的功夫了得啊!
【在 l******e 的大作中提到】 : the most significant, the least significant : 比较错误的话,楼主就可能有的keys在map里被当成一个key了;但是楼主其他的code就 : 不这么认为了。 : : matter how the human logic works.
|
d****p 发帖数: 685 | 16 Your are right.
The original operator is not a strict weak ordering.
S1(0, 1, 2) < S2(0, 2, 1)
S1(0, 2, 1) < S2(0, 1, 2)
When I was drawing an if-else tree, I missed the second true case on the 3rd
level. And it really shows nested if-else is hard to read :-)
【在 l******e 的大作中提到】 : 错了吧 : l1是tms,l3是tls,他的第二个else if就错了
|
d****p 发帖数: 685 | 17 Actually your original operator satisfies:
A not less than A
It doesn't satisfy if A less than B then B not less than A. So the nodes in
the map are misplaced and no longer form a binary search tree. As a result,
it may fail to locate existing nodes (when using []?) and treat values of
such nodes as 0.
The interesting thing is sometimes you get result right - it really depends
on how these faulty nodes are placed inside the tree. An example is if all
of them happen to stay on the right sub tree of the root node, retrieval on
any nodes on the left sub tree will be fine.
【在 s****a 的大作中提到】 : 理论上确实不影响,但是我定义的比较算附对于相同的对象会得出true的结果,那就是 : 错了,执行起来就一片混乱 : : matter how the human logic works.
|
b********n 发帖数: 609 | 18 唉,您这逻辑性也太差了吧。
【在 s****a 的大作中提到】 : l_set就是三个整数,我把<的定义也贴上来了,应该很简单 : struct l_set {int l1;int l2;int l3;}; : inline bool operator < (const l_set set1, const l_set set2)) : { : if (set1.l1: return true; : else if (set1.l1==set2.l1 && set1.l2: return true; : else if (set1.l2==set2.l2 && set1.l3: return true;
|
t****t 发帖数: 6806 | 19 呵呵, 往往越是简单的东西越容易搞错
其实你根本没必要自己写, 直接写tuple就好了, op<是自动的
【在 s****a 的大作中提到】 : l_set就是三个整数,我把<的定义也贴上来了,应该很简单 : struct l_set {int l1;int l2;int l3;}; : inline bool operator < (const l_set set1, const l_set set2)) : { : if (set1.l1: return true; : else if (set1.l1==set2.l1 && set1.l2: return true; : else if (set1.l2==set2.l2 && set1.l3: return true;
|
d****p 发帖数: 685 | 20 Oh yeah, that's good trick. And it is smart by skipping comparison of
elements whose comparator is not defined.
tuple's comparator is lexicographical. To make it run fast, we may need to
order the argument list in a way that the type with most value variation
comes first so as to minimize unnecessary internal comparisons.
【在 t****t 的大作中提到】 : 呵呵, 往往越是简单的东西越容易搞错 : 其实你根本没必要自己写, 直接写tuple就好了, op<是自动的
|
j******n 发帖数: 271 | 21 more efficient hand coding:
inline bool operator < (const l_set& x, const l_set& y))
{
return (x.l1 < y.l1) || !(y.l1 < x.l1) ||
(x.l2 < y.l2) || !(y.l2 < x.l2) ||
(x.l3 < y.l3);
} |
v*s 发帖数: 946 | 22 要是我就这么写,比较符合人类的习惯。
if (x.l1 < y.l1) return true;
if (x.l1 == y.l1 && x.l2 < y.l2) return true;
if (x.l1 == y.l1 && x.l2 == y.l2 && x.l3 < y.l3) return true;
return false;
貌似和营长的等价,不过我觉得更容易阅读。
【在 j******n 的大作中提到】 : more efficient hand coding: : inline bool operator < (const l_set& x, const l_set& y)) : { : return (x.l1 < y.l1) || !(y.l1 < x.l1) || : (x.l2 < y.l2) || !(y.l2 < x.l2) || : (x.l3 < y.l3); : }
|