2012-05-02 3 views
0

У меня есть оператор if, который сравнивает строки, но я хочу сравнить строки, которые имеют одни и те же слова, но разные порядки, и возвращать их как истинные.Сравнение строк, которые имеют разный порядок

строка 1 а, б, в

строка 2 б, с, а

Как я могу сравнить их и, если заявление рассматривают его как ту же строку?

+0

Я бы попытаться найти аа способ получить их в правильном порядке, чтобы начать с :) Все ответы ниже - это потрясающе, но если вы можете их отсортировать, чтобы начать с этого, это будет намного эффективнее сравнивать! – deanWombourne

+0

Я думаю, что это возможно без сортировки вообще –

+0

@deanWombourne Теперь я отправил ответ, не сортируя ничего –

ответ

5

Отделите строку, используя компонентыSeperatedByString: используя любую строку, разделите ваши слова (запятую, пробел) и поместите результат в NSSet. Сделайте это для обеих строк и сравните множества для равенства.

Модифицированный метод с использованием mutableArray вместо набора для съемки проблемы с дублированием строк во внимание (как описано в комментариях):

-(BOOL) string: (NSString*) string1 isEqualTo: (NSString*) string2 { 
    if (string1.length != string2.length) return NO; 
    if ([string1 isEqualToString: string2]) return YES; 

    NSMutableArray *array1 = [NSMutableArray arrayWithArray: [string1 componentsSeperatedByString: @","]]; 
    NSMutableArray *array2 = [NSMutableArray arrayWithArray: [string2 componentsSeperatedByString: @","]]; 

    [array1 sortUsingSelector: @selector(compare:)]; 
    [array2 sortUsingSelector: @selector(compare:)]; 

    return [array1 isEqualToArray: array2]; 
} 
+0

+1 таким образом заказ просто игнорируется. – Till

+0

Правильно ... – Mario

+2

... Но a, c, a, b и a, b, c будут сравнивать с YES. Не знаю, если это было предназначено –

2

Split каждая строка в массив слов. Сортируйте массивы. Затем сравните каждое слово в массивах.

NSString *string1 = @"This is a test"; 
    NSString *string2 = @"test a is This"; 
    NSArray *wordsOne = [string1 componentsSeparatedByString:@" "]; 
    NSArray *wordsTwo = [string2 componentsSeparatedByString:@" "]; 

    NSMutableArray *wordsOneCopy = [NSMutableArray arrayWithArray:wordsOne]; 
    NSMutableArray *wordsTwoCopy = [NSMutableArray arrayWithArray:wordsTwo]; 

    [wordsOneCopy removeObjectsInArray:wordsTwo]; 
    [wordsTwoCopy removeObjectsInArray:wordsOne]; 

    if (wordsOneCopy.count == 0 && wordsTwoCopy.count == 0) // the strings contained the same words, perhaps different order 
+0

То же, что и с наборами: «ABC» будет равно «ACAB» или даже «ABCD», в то время как это будет неверно, если вы измените порядок предложений « –

+0

@Kai Спасибо. Очевидная ошибка. Должно быть исправлено сейчас. – mweathers

1

Если ваши строки всегда будут в этом разделенном запятыми формата, попробуйте написать метод, который возвращает BOOL, который разбивает строку друг от друга, а затем сравнивает содержимое. (Написание этого грязного стиля ARC).

-(BOOL)compareWordsInString:(NSString*)stringA withString:(NSString*)stringB 
{ 
    NSArray *arrayA = [stringA componentsSeparatedByString:@","]; 
    NSArray *arrayB = [stringB componentsSeparatedByString:@","]; 
    NSSet *setA = [[NSSet alloc] initWithArray:arrayA]; 
    NSSet *setB = [[NSSet alloc] initWithArray:arrayB]; 

    return [setA isEqualToSet:setB]; 
} 

Затем вы можете вызвать этот метод в вашей if:

if([self compareWordsInString:@"a,b,c" withString:@"b,c,a"]) 
{ 
    // do work 
} 

Заметьте, что это не будет работать должным образом, если количество слов должно точно соответствовать и иметь ровно один матч корреспондент в вторая строка, как NSSet, будет оценивать ДА при сравнении @"a,a,b,b,c,c,c" с @"a,b,c", потому что каждый объект будет добавлен только один раз.

+0

Это вызывает утечку памяти (в среде, отличной от ARC). – Mario

+0

Да, я знаю. Это «код ARC». :) – Mark

0

Что вы можете сделать, это превратить компоненты строки (слова) в массив, отсортировать массив и сравнить. Таким образом, вы сравните слова, а не порядок.

Вот пример:

NSMutableArray *array1 = [NSMutableArray arrayWithArray:[string1 componentsSeparatedByString:@","]]; 
NSMutableArray *array2 = [NSMutableArray arrayWithArray:[string2 componentsSeparatedByString:@","]]; 

NSComparator comparator = ^(NSString *s1, NSString *s2) { 
    return [s1 compare:s2]; 
}; 

[array1 sortUsingComparator:comparator]; 
[array2 sortUsingComparator:comparator]; 

if ([array1 isEqualToArray:array2]) 
{ 
    //do work 
} 

[array1 isEqualToArray:array2] вызов будет сказать вам, если строки похожи.

Редактировать

В ответ на @ deanWombourne свой комментарий, я изменил свой первоначальный код с участием NSSet S в коде выше, так что благодаря @deanWombourne за правильным и полезным комментарием. (. И благодаря @Kai для вызова меня на плохой editting не повторится.)

+1

Вы можете использовать 'a, a, b' то же, что и 'a, b', что не так :) (Хотя, если есть ограничение на дубликаты слов, они в порядке!) – deanWombourne

+1

Плохое редактирование! Теперь формально правильный и полезный комментарий @deanWombourne не делает любой смысл и кажется неправильным для читателей, которые не видели оригинальный пост. –

0

Без сортировки:

-(BOOL)isSameWordsInString:(NSString *)string1 andString:(NSString *)string2 
{ 
    if(string1.length != string2.length) 
    { 
    return NO; 
    } 
    if([string1 isEqualToString:string2]) 
    { 
    return YES; 
    } 
    NSMutableArray *array1 = [NSMutableArray arrayWithArray:[string1 componentsSeparatedByString:@" "]]; 
    NSMutableArray *array2 = [NSMutableArray arrayWithArray:[string2 componentsSeparatedByString:@" "]]; 
    if(array1.count != array2.count) 
    { 
    return NO; 
    } 
    for(NSString *word in array1) 
    { 
    if(![array2 containsObject:word]) 
    { 
     return NO; 
    } 
    //EDIT on comment by deanWombourne 
    [array2 removeObject:word]; 
    //END EDIT 
    } 
    return YES; 
} 
+0

Как насчет 'a, b, c, c' и 'a, b, c, d' - ваш метод вернет их как равные :( – deanWombourne

+0

2deanWombourne Хорошая точка, думаю, я исправил ее –

Смежные вопросы