1

私はアプリ (Cocoa Touch、Web ブラウザー) を持っていますが、NSString を他の何千もの文字列と比較できるようにする必要があります。これが取引です。

WebView が読み込まれると、URL が取得されます。この URL を文字通り何千もの結果 (27,847) と比較する必要があります。これらの各数値は、プレーン テキスト ファイル内のテキスト行を表します。

テキスト ファイルからデータを取得し、それを NSString と比較する最良の方法を知りたいです。WebView が読み込んでいる URL にこれらの文字列が含まれているかどうかを知る必要があります。

アプリは非常に高速である必要があるため、テキスト ファイルのすべての行を解析して配列に変換し、すべての結果を比較するだけでは不十分です。

あなたのアイデアを共有してください。ありがとう。

4

5 に答える 5

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 サービスを削除するアプローチを強くお勧めします。

于 2012-12-12T16:22:08.933 に答える
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;
    }
}];
于 2012-12-12T16:44:52.913 に答える
1

これは正規表現の仕事です。探している/フィルタリングしているすべての部分文字列を取得し、それらを適切にエスケープし ( []|\などの文字を でエスケープします\)、それらを . で結合します|。結果の文字列は、各 URL に適用する正規表現です。

部分文字列でいっぱいの配列全体をループすることもできrangeOfString:options:ますが、それは遅い方法です。この種のことのために、優れた正規表現の実装が構築されており、 Apple の実装が適切であることを願っています。

とは言っても、それから地獄をプロファイリングしてください。いくつかの正規表現の実装が|演算子を詰まらせるのを見たので、Apple の実装がそれらの 1 つでないことを確認する必要があります。

于 2012-12-13T07:28:27.067 に答える
0

最初に試してみることをお勧めしますNSDictionary。これにすべての URL をロードできます。内部的には、非常に高速な (O(1)) ルックアップのために、ある種のハッシュ テーブル/マップが使用されます。

その後、 の結果を確認でき[dictionary objectForKey:userURL]ます。何かが返された場合、URL は辞書内の URL と一致しました。

これに関する唯一の問題は、正確な文字列の一致が必要なことです。辞書に含まれhttp://server/foobarていてユーザーが入力するとhttp://server/FOOBAR(大文字と小文字を区別しないサーバーであるため)、ルックアップでミスが発生します。同様に、?foobarURL の末尾にクエリを追加すると、ミスが発生します。を使用して明示的なポートを追加することもできます。文字エンコーディングを使用するserver:80%XX、同じ URL の何百ものバリエーションを作成できます。これを考慮して、辞書内の URL と、ルックアップの前にユーザーが入力した URL の両方を正規化する必要があります。

于 2012-12-12T16:34:21.583 に答える
0

テキスト ファイル内の各文字列を比較する必要がある場合は、それを比較する必要があります。

ただし、ロード中または何かを表示している間にバックグラウンド スレッドで実行すると、アプリが動かなくなったように感じることはありません。

于 2012-12-12T16:22:18.147 に答える