【问题标题】:Sorting arrays with cyclic compares (infinite loop?)使用循环比较对数组进行排序(无限循环?)
【发布时间】:2010-02-24 17:00:03
【问题描述】:

我有一些对象有 3 个排序选项:质量、数量和与另一个对象的比较,按该顺序排序。

- (NSComparisonResult) compare: (MyObject *) obj {
if (self.quality > obj.quality)
return NSOrderedAscending;
else if (self.quality < obj.quality)
return NSOrderedDescending;

if (self.quantity > obj.quantity)
return NSOrderedAscending;
else if (self.quantity < obj.quantity)
return NSOrderedDescending;

if ([self betterThan: obj])
return NSOrderedAscending;

if ([obj betterThan: self])
return NSOrderedDescending;

return NSOrderedSame;
}

我的问题是,如果对象具有相同的质量和数量,betterThan: 方法可能会导致循环比较,在这种情况下我想返回任何排序顺序。

例如,A、B 和 C 的质量/数量相同,但是

A betterThan: B => YES
B betterThan: C => YES
C betterThan: A => YES

解决方案?谢谢。

【问题讨论】:

    标签: iphone sorting arrays compare


    【解决方案1】:

    我对您的代码和您的问题有些困惑。您拥有的比较功能看起来只会比较质量(第一个分支的两个分支如果有返回)。如果您只想在比较中使用 betterThan (我认为这是您面临的问题..)我会这样做:

    - (NSComparisonResult) compare: (MyObject *) obj {
        if ([self betterThan: obj])
            if ([obj betterThan: self])
                return NSOrderedSame
            else
                return NSOrderedAscending;
        else
            return NSOrderedDescending
    }
    

    【讨论】:

    • 我已经采取了预防措施,使两个对象永远不会比彼此更好,这样情况就不会真正发生。但是,对于可能发生的 3 个对象。排序函数将一次获取 2 个对象并使用比较函数进行比较。对于我上面描述的 3 个对象(A、B、C),我的应用程序只是崩溃而没有调试器输出。
    【解决方案2】:

    您应该让betterThan: 方法返回NSOrderedSame。所有返回NSComparisonResult 的方法应该总是能够返回所有三个选项。

    你的方法永远不会通过第一个 if -block:

    if (self.quality > obj.quality)
        return NSOrderedAscending;
    else
        return NSOrderedDescending; //<== returns for both self.quality > obj.quality AND self.quality == obj.quality
    

    由于比较必须具有三个结果之一,但您只测试一个,因此您将始终从该 if 块中的方法返回。其他任何逻辑都不会被使用。

    您需要嵌套 if 块来获取过滤逻辑。测试它们是否更大或更小并返回,但如果它们相同,则进入下一个测试。根据需要重复。

    - (NSComparisonResult) compare: (MyObject *) obj {
        if (self.quality > obj.quality)
            return NSOrderedAscending;
        else if (self.quality < obj.quality)
            return NSOrderedDescending; 
        else {
            if (self.quantity > obj.quantity)
                return NSOrderedAscending;
            else if (self.quantity < obj.quantity)
                return NSOrderedDescending;
            else {
                ... and so on
            }
        }
    

    我认为每个属性比较都应该有自己的方法。然后,如果您需要全面比较该类的两个对象,您可以将它们组合成一个大比较。

    在这种情况下,betterThan: 方法似乎是您的实际类比较。

    【讨论】:

    • 是的,你是对的,我写的代码很匆忙。我修复了:) 但是,删除所有其他比较并坚持使用 betterThan: 作为我唯一的比较,我所得到的一切都崩溃了,因为它不会停止排序,我相信。我没有从调试器得到任何输出,所以我真的不能说。
    【解决方案3】:

    好的,我发现这个错误与排序无关(尽管它似乎是由它引起的)。

    显然这确实有效。如果出现死锁,系统将停止排序。

    无论如何,感谢您的宝贵时间。 :)

    【讨论】:

      猜你喜欢
      • 2021-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-07
      • 1970-01-01
      • 1970-01-01
      • 2021-05-07
      • 2017-08-26
      相关资源
      最近更新 更多