Поиск строк NSStrings из одного массива в другом (для циклов и проблемы isEqualToString) - PullRequest
0 голосов
/ 17 октября 2011

Я хочу добавить объекты из NSArray * small, если их нет в NSArray * big. Но вывод показывает, что объекты из * small, которые существуют в * big, добавляются. Я пробовал x isEqualToString: x == NO (я знаю, что это не то же самое, что range.location и hasPrefix, но странно, что даже hiya -> добавляется, когда он существует в * big) и range.location = NSNotFound и x hasPrefix: x == NO. Но ни один из них не работает. Почему?

Кстати, * small содержит меньше объектов, чем * big. Имеет ли это значение?

Коды ниже:

NSArray *big = [[NSArray alloc] initWithObjects:@"hello ->hi", @"hiya ->", @"hiya ->whatever", @"hiya -> howdy", @"good day ->hello", @"nope, but ->no", @"however ->what", @"May ->april", @"mai ->", nil];
NSArray *small = [[NSArray alloc] initWithObjects: @"match", @"hiya ->",@"hiya ->", @"hiya ->",@"nope, but ->", @"however ->", @"May ->", nil];


NSString *same;

NSMutableArray *newWords = [[NSMutableArray alloc]init];
newWords = [NSMutableArray  arrayWithArray: big];

NSLog (@"big: %@", big);


int i;
for (i = 0; i<[small count]; i++)

{
    same = [small objectAtIndex:i];
    for (NSString *s in big)
    {
        //NSRange ran = [s rangeOfString:same];
        //if (ran.location =NSNotFound)
        //if ([s isEqualToString: same] == NO)

        if ([s hasPrefix:same] == NO)

        {
            [newWords addObject:same];
            break;
        }
    }
}

Вывод показывает:

2011-10-17 19:21:56.855 scanner2[4018:207] newWords: (
    "hello ->hi",
    "hiya ->",
    "hiya ->whatever",
    "hiya -> howdy",
    "good day ->hello",
    "nope, but ->no",
    "however ->what",
    "May ->april",
    "mai ->",
    match,
    "hiya ->",
    "hiya ->",
    "hiya ->",
    "nope, but ->",
    "however ->",
    "May ->"
)

edit: я даже пытался if ([x compare: x ] !=NSOrderedSame), но только hiya -> добавляется трижды в * newWords.

Ответы [ 2 ]

4 голосов
/ 17 октября 2011

Вы сравниваете каждую строку в Small с каждой строкой в ​​Big. Если ЛЮБАЯ из строк в Big не совпадает с той, которую вы сравниваете, вы добавляете ее в Big. Но на самом деле вы хотите добавить его, если ВСЕ строки не совпадают. Итак, вам нужно подождать, пока после проверки всего большого массива.

Попробуйте вместо этого:

for (NSString *same in small) {
    BOOL found = NO;
    for (NSString *s in big) {
        if ([s hasPrefix:same] == YES) {
            found = YES;
            break;
        }
    }
    if (!found) {
       [newWords addObject:same];
    }
}

Чтобы быть педантичным, я должен добавить, что если массивы будут НАМНОГО больше, чем демонстрационные строки, которые вы показываете, то вы можете сохранить Big как отсортированный массив, так что вы можете найти присутствие или отсутствие намного быстрее.

Например:

NSArray *big = [[NSArray alloc] initWithObjects:@"hello ->hi", @"hiya ->", @"hiya ->whatever", @"hiya -> howdy", @"good day ->hello", @"nope, but ->no", @"however ->what", @"May ->april", @"mai ->", nil];
NSArray *small = [[NSArray alloc] initWithObjects: @"match", @"hiya ->",@"hiya ->", @"hiya ->",@"nope, but ->", @"however ->", @"May ->", @"match",nil];

NSDate *start = [NSDate date];

NSMutableArray *newWords = [NSMutableArray  arrayWithArray: big];

for (NSString *same in small) {
    BOOL found = NO;
    for (NSString *s in big) {
        if ([s isEqualToString:same] == YES) {
            found = YES;
            break;
        }
    }
    if (!found) {
        [newWords addObject:same];
    }
}

NSLog(@"Time for original method: %fms ",-[start timeIntervalSinceNow]*1000);

start = [NSDate date];
/*
 static NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch;
 NSLocale *currentLocale = [NSLocale currentLocale];
 NSComparator sort = ^(id string1, id string2) {
 NSRange string1Range = NSMakeRange(0, [string1 length]);
 return [string1 compare:string2 options:comparisonOptions range:string1Range locale:currentLocale];
 };*/

NSComparator sort = ^(id s1, id s2) { return [s1 compare:s2]; };

newWords = [NSMutableArray arrayWithArray: 
            [big sortedArrayUsingComparator:sort]]; 

for (NSString *same in small) {
    NSUInteger i = [newWords indexOfObject:same 
                             inSortedRange:NSMakeRange(0, [newWords count]) 
                                   options:NSBinarySearchingInsertionIndex 
                           usingComparator:sort ];
    if (![same isEqualToString:[newWords objectAtIndex:i]] ) {
        [newWords insertObject:same atIndex:i];
    }
}
//    }
NSLog(@"Time for new method: %fms ",-[start timeIntervalSinceNow]*1000);
[big release];
[small release];

Очевидно, что если вы делаете это несколько раз, просто сохраняйте большой размер как отсортированный изменяемый массив, а не пересортируйте его каждый раз.

1 голос
/ 17 октября 2011

Твоя логика плохая.Вы должны закончить полный цикл, чтобы добавить элемент, вы добавляете его слишком рано.Вы должны проверить, что у всех в целом нет этого префикса (не некоторые из них).

...