0

FactorHelper定義が以下のように呼ばれる目的の C クラスがあります。の である factor と呼ばれるプロパティがありNSMutableArrayますNSNumbersisEqual:このクラスには、2 つのオブジェクトの factor プロパティFactorHelperの数値が同じ場合 (数値の順序が異なっていても)、 true を返すカスタムメソッドがあります。

10,5,2と10,2,5 の 2 つのFactorHelperオブジェクトを作成してテストしようとしました。次に を作成し、firstObject を追加してから 2 番目のオブジェクトを追加しました。2 番目のオブジェクトが追加されないことを期待していましたが、追加されていることがわかります。コードをステップ実行すると、 addObject によって呼び出され、 が返されていることがわかります。私は何を間違っていますか?NSMutableSetisEqualTRUE

アップデート

を変更する[NSMutableSet new][NSMutableSet alloc] init]、期待どおりに機能します。

また、TRUE、FALSE をすべて YES、NO に変更すると、正しく動作します (そのままにしておいても[NSMutableSet new])。

何が起こっているのかわかりません。誰かが光を当てることができますか?!

クラス定義

@interface FactorHelper: NSObject
 @property NSMutableArray <NSNumber *> *factors;
 -(BOOL) isEqual:(FactorHelper *)other;
 -(instancetype) initWithFactors:(NSMutableArray *)factors;
 -(NSString *) description;
@end

@implementation FactorHelper

- (instancetype) initWithFactors:(NSMutableArray *)factors
{
    self = [super init];

    if (self) {
        _factors = factors;
    }

    return self;
}

-(BOOL) isEqual:(FactorHelper *)other
{
    if ([self.factors count] != [other.factors count])
    {
        return FALSE;

    }
    else
    {
        NSMutableDictionary <NSNumber *, NSNumber *> *myHashTable = [[NSMutableDictionary alloc] init];
        for (NSNumber *nextNumber in self.factors) {
            if(myHashTable[nextNumber] == nil)
            {
                myHashTable[nextNumber] = @(1);
            }
            else
            {
                myHashTable[nextNumber] = @([myHashTable[nextNumber] integerValue]+1);
            }
        }

        for (NSNumber *nextNumber in other.factors)
        {
            if(myHashTable[nextNumber] == nil)
            {
                return FALSE;
            }
            else
            {
                myHashTable[nextNumber] = @([myHashTable[nextNumber] integerValue] - 1);

                if ([myHashTable[nextNumber] integerValue] == 0) {
                    [myHashTable removeObjectForKey:nextNumber];
                }
            }
        }

        if ([[myHashTable allKeys] count] == 0)
        {
            return TRUE;
        }
        else
        {
            return FALSE;
        }

    }
}
@end

単体テスト コード

NSMutableSet *testSet = [NSMutableSet new];
FactorHelper *fact1 = [[FactorHelper alloc] initWithFactors:[@[@(10),@(5),@(2)] mutableCopy]];
FactorHelper *fact2 = [[FactorHelper alloc] initWithFactors:[@[@(10),@(2),@(5)] mutableCopy]];
[testSet addObject:fact1];
[testSet addObject:fact2];
NSLog(@"Are factors 1 and 2 the same: %d",[fact1 isEqual:fact2]);
4

2 に答える 2

2

NSMutableSetハッシュ値ベースのセットです。hashと一致する要素タイプのメソッドをオーバーライドする必要がありますisEqual:

あなたの場合、次のようなものです:

- (NSUInteger)hash {
    NSCountedSet *factorCounts = [[NSCountedSet alloc] initWithArray:self.factors];
    return [@"FactorHelper" hash] + [factorCounts hash];
}

追加されているかどうかをどのように確認したかはわかりませんが、これFactorHelperNSMutableSet.

ちなみに、 をisEqual:使用すると、もう少し短く実装できますNSCountedSet

-(BOOL) isEqual:(FactorHelper *)other {
    NSCountedSet *myFactorCounts = [[NSCountedSet alloc] initWithArray:self.factors];
    NSCountedSet *otherFactorCounts = [[NSCountedSet alloc] initWithArray:other.factors];
    return [myFactorCounts isEqual:otherFactorCounts];
}

これは、上記との一貫性をより明確に示していhashます。

于 2016-07-30T21:23:49.920 に答える
1

あなたのコードは動作しているように見えたとしても、決して動作しませんでした。

isEqual問題は、 Set でクラスを機能させるための唯一の要件がのカスタム実装ではないことです。考えてみてください:セットとは何ですか? ハッシュテーブルです。したがって、一致するカスタム実装も提供する必要がありhashます — そして、あなたはそれをしていません.

ハッシュ可能性の要件は次のとおりです。2 つのオブジェクトが等しい場合、2 つのオブジェクトのハッシュ値は同じでなければなりません。

于 2016-07-30T21:23:12.097 に答える