Objective-c:快速模糊搜索匹配

时间:2013-02-21 21:36:12

标签: objective-c cocoa search levenshtein-distance fuzzy-search

有没有人知道Objective-c的模糊搜索匹配的快速实现? (levenshtein距离算法)。

我发现了这个:https://github.com/thetron/StringScore/blob/master/NSString%2BScore.m - 但遗憾的是它很慢。我需要将它与大约200个字符串进行比较,并且它是连续的 - 每次键入新键击。

有什么想法吗?

2 个答案:

答案 0 :(得分:10)

如果NSString + Score做你想要的但速度太慢,你可以从加速它开始。 -scoreAgainst:fuzziness:options:中的第23到28行是设置代码,只需要执行一次,而不是每次进行200次比较。因此,将该代码拉入设置方法并再次测量。

编辑:

作为练习,我forked StringScore,提取设置代码并进行微小的更改以获得一些性能改进,然后进行测量。我使用了1000个随机单词,将它们分成三个(例如“中断点饮用”)。对于这些组中的每一组,我进行了设置(如本原始答案中所述),然后将字符串与所有1000组进行比较。我的Core 2 Duo大约需要11秒钟。

因此将一个单词与1000进行比较大约需要11毫秒。现在你只需要1到200,所以它可能不到10毫秒。这对你有用吗?

(顺便说一下,将近一半的时间仍然花在rangeOfString上:找到一个字符;这可能要快得多,但我不想深入了解算法的细节。)

答案 1 :(得分:2)

我不知道你在Objective-C中实现的算法

您是否有理由不使用NSPredicate与CoreData的内置功能。我发现这非常快速搜索超过200个字符串。

例如,给定NSString * searchText和fetchedResultsController

NSPredicate * predicate = [NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@", searchText];

self.filteredListContents = [[[self fetchedResultsController] fetchedObjects] filteredArrayUsingPredicate:predicate];

你也可以在NSArray上使用NSPredicate,我认为你已经尝试过,发现它太慢了。

来自苹果文档

NSMutableArray *array =
[NSMutableArray arrayWithObjects:@"Nick", @"Ben", @"Adam", @"Melissa", nil];

NSPredicate *bPredicate = [NSPredicate predicateWithFormat:@"SELF beginswith[c] 'a'"];

NSArray *beginWithB = [array filteredArrayUsingPredicate:bPredicate];
// beginWithB contains { @"Adam" }.

NSPredicate *sPredicate = [NSPredicate predicateWithFormat:@"SELF contains[c] 'e'"];

[array filterUsingPredicate:sPredicate];
// array now contains { @"Nick", @"Ben", @"Melissa" }

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html