以这种方式比较NSString的最有效方法是什么

时间:2012-12-12 16:17:01

标签: objective-c performance cocoa-touch parsing comparison

我有一个应用程序(Cocoa Touch,Web浏览器),但我需要能够将NSString与数千个其他字符串进行比较。这是交易。

加载WebView时,我会获取URL。我需要将这个URL与数千个结果进行比较(27,847)。每个数字代表纯文本文件中的一行文本。

我想知道从文本文件中获取数据并将其与NSString进行比较的最佳方法。我需要知道WebView加载的URL是否包含任何这些字符串。

应用程序需要非常快,所以我不能只解析文本文件中的每一行,将其转换为数组,然后比较每个结果。

请分享您的想法。感谢。

5 个答案:

答案 0 :(得分:2)

我认为最干净的解决方案是:

  • 创建一个可以将工作卸载到服务器并返回响应的Web服务。由于听起来您正在构建Web保护服务,因此随着时间的推移,您的数据库可能会变得非常大,您可以扩展服务器以提高其速度。此外,您不希望每次查找数据发生更改时都必须更新您的应用程序。

其他选项包括:

  • 使用本地SQLite数据库。 SQL数据库应该相对快速地执行查找。

  • 如果您不想使用任何数据库,您是否尝试将所有搜索字符串放入NSDictionary或NSMutableDictionary对象?这样,您只需检查您要搜索的字符串的valueForKey:是否为nil。

此示例代码:

NSDictionary *searchDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                  [NSNumber numberWithBool:YES], @"google.com",
                                  [NSNumber numberWithBool:YES], @"yahoo.com",
                                  [NSNumber numberWithBool:YES], @"bing.com",
                                  nil];

NSString *searchString = @"bing.com";

if ([searchDictionary valueForKey:searchString]) {
    // search string found
} else {
    // search string not found
}

注意:如果您希望NSDictionary执行不区分大小写的比较,请将所有值预加载为小写,并在使用valueForKey时使搜索字符串小写:。

这可以采取多少内存是另一个故事,但我不知道如何在本地更快地进行这种比较。不过,我强烈建议使用删除Web服务方法。

答案 1 :(得分:1)

从文件中创建一个字符串并通过这些行进行枚举。

NSString *stringToCheck;

NSData *bytesOfFile = [NSData dataWithContentsOfFile:@"/path/myfile.txt"];
NSString *fileString = [[NSString alloc] initWithData:bytesOfFile
                                              encoding:NSUTF8Encoding];
__block BOOL foundMatch = NO;

[fileString enumerateLinesUsingBlock:^(NSString *line, BOOL *stop){
    if([stringToCheck isEqualToString:line]){
        *stop = YES;
        foundMatch = YES;
    }
}];

答案 2 :(得分:1)

这是正则表达式的工作。获取您正在寻找/过滤的所有子字符串,适当地转义它们(转义[]|\等字符,以及使用\),并使用|加入它们。生成的字符串是您的正则表达式,您可以将其应用于每个URL。

可以循环遍历整个子串的数组,每个子串都做rangeOfString:options:,但这是缓慢的方式。 A good regular expression implementation is built for this sort of thing,我希望Apple's implementation合适。

那就是说,了解它的地狱。我在|运算符上看到了一些正则表达式实现,所以你要确保Apple不是其中之一。

答案 3 :(得分:0)

如果您需要比较文本文件中的每个字符串,您将不得不对它进行比较,而不是围绕它。

然而,你可以做的是在显示一些加载或其他东西时在后台线程上做,并且它不会觉得应用程序卡住了。

答案 4 :(得分:0)

我建议您首先尝试使用NSDictionary。您可以将所有URL加载到此内部,并在内部使用某种哈希表/映射进行非常快速(O(1))查找。

然后,您可以检查[dictionary objectForKey:userURL]的结果,如果它返回了某些内容,那么该网址与字典中的网址匹配。

唯一的问题是它需要精确的字符串匹配。如果您的字典包含http://server/foobar并且用户输入http://server/FOOBAR(因为它是不区分大小写的服务器),那么您将错过查找。同样,在网址末尾添加?foobar个查询会导致错过。您还可以使用server:80添加显式端口,并使用%XX字符编码创建数百个相同网址的变体。您必须对此进行说明并规范化词典中的URL以及用户在查找之前输入的URL。