gpt4 book ai didi

objective-c - 为地理坐标类实现 -hash 和 -isEqual

转载 作者:太空宇宙 更新时间:2023-11-04 04:03:47 25 4
gpt4 key购买 nike

我有一个存储纬度/经度/高度的对象,需要可靠快速 -hashisEqual 实现。我正在使用 double 来存储所有基元。

Best practices for overriding isEqual: and hash 的可接受答案, 看起来不错,但它只讨论 integer 值。

我的问题是如何处理 double ,因为它们不是精确值。我想比较小数点后 8 位以内的图元,这已经比 GPS 芯片本身准确多了。

这是我到目前为止的想法,我做得对还是需要改进?

我的 -isEqual: 实现相当简单:

- (BOOL)isEqualToAGPoint:(AGPoint *)otherPoint
{
if (fabs(otherPoint->latitude - latitude) > 0.00000001)
return NO;

if (fabs(otherPoint->longitude - longitude) > 0.00000001)
return NO;

if (fabs(otherPoint->altitude - altitude) > 0.00000001)
return NO;

return YES;
}

但我不太确定我的-hash 实现:

- (NSUInteger)hash
{
NSUInteger prime = 31;
NSUInteger result = 1;

result = prime * result + lround(latitude * 100000000);
result = prime * result + lround(longitude * 100000000);
result = prime * result + lround(altitude * 100000000);

return result;
}

快速测试表明它似乎可以按我的需要工作:

// all three have the same longitude and altitude, while a and b have slightly different (but should be considered identical) latitudes, while c's latitude is just different enough to be considered not equal to the a and b
AGPoint *a = [[AGPoint alloc] initWithLatitude:-16.922608127 longitude:145.77124538 altitude:2.74930134];
AGPoint *b = [[AGPoint alloc] initWithLatitude:-16.922608128 longitude:145.77124538 altitude:2.74930134];
AGPoint *c = [[AGPoint alloc] initWithLatitude:-16.922608147 longitude:145.77124538 altitude:2.74930134];

NSLog(@"a == b: %i", (int)[a isEqual:b]);
NSLog(@"a == c: %i", (int)[a isEqual:c]);
NSLog(@"hash for a: %lu b: %lu c: %lu", (unsigned long)[a hash], (unsigned long)[b hash], (unsigned long)[c hash]);

output:
a == b: 1
a == c: 0
hash for a: 3952407433 b: 3952407433 c: 3952405511

这看起来正确吗?

最佳答案

您遇到了像 (0.5 ± 0.015625)*1e-8 这样的值。坐标的绝对差小于公差,但四舍五入导致不同的整数。

编辑:

这意味着两个对象可以被认为是相等的,但具有不同的哈希码。如果您使用 HashMap ,不一致的相等性和哈希码可能会造成严重的问题。

一个解决方案是在 isEqual 中比较每个对象的哈希值:

- (BOOL)isEqualToAGPoint:(AGPoint *)otherPoint
{
if ([otherPoint hash] != [self hash])
return NO;

if (fabs(otherPoint->latitude - latitude) > 0.00000001)
return NO;

if (fabs(otherPoint->longitude - longitude) > 0.00000001)
return NO;

if (fabs(otherPoint->altitude - altitude) > 0.00000001)
return NO;

return YES;
}

关于objective-c - 为地理坐标类实现 -hash 和 -isEqual,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8691789/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com