iOS フレームワークでは、次の 3.2 MB ファイルで発音を検索しています: https://cmusphinx.svn.sourceforge.net/svnroot/cmusphinx/trunk/pocketsphinx/model/lm/en_US/cmu07a.dic
NSRegularExpression を使用して、NSArray として指定された任意の単語セットを検索しています。検索は、大きなファイルの内容を NSString として実行されます。改行とタブ文字で囲まれた単語を一致させてから、行全体を取得する必要があります。たとえば、NSArray に「monday」という単語がある場合、辞書ファイル内のこの行を一致させたいとします。
monday M AH N D IY
この行は改行で始まり、文字列「monday」の後にタブ文字が続き、その後に発音が続きます。最終的な出力を得るには、正規表現によって行全体が一致する必要があります。また、次のようにリストされている単語の別の発音を見つける必要があります。
monday(2) M AH N D EY
代替発音は常に (2) で始まり、(5) まで上がります。そのため、改行とタブ文字で囲まれた単一の数字を含む括弧が続く単語の反復も検索します。
次のように、100% 動作する NSRegularExpression メソッドがあります。
NSArray *array = [NSArray arrayWithObjects:@"friday",@"monday",@"saturday",@"sunday", @"thursday",@"tuesday",@"wednesday",nil]; // This array could contain any arbitrary words but they will always be in alphabetical order by the time they get here.
// Use this string to build up the pattern.
NSMutableString *mutablePatternString = [[NSMutableString alloc]initWithString:@"^("];
int firstRound = 0;
for(NSString *word in array) {
if(firstRound == 0) { // this is the first round
firstRound++;
} else { // After the first iteration we need an OR operator first.
[mutablePatternString appendString:[NSString stringWithFormat:@"|"]];
}
[mutablePatternString appendString:[NSString stringWithFormat:@"(%@(\\(.\\)|))",word]];
}
[mutablePatternString appendString:@")\\t.*$"];
// This results in this regex pattern:
// ^((change(\(.\)|))|(friday(\(.\)|))|(monday(\(.\)|))|(saturday(\(.\)|))|(sunday(\(.\)|))|(thursday(\(.\)|))|(tuesday(\(.\)|))|(wednesday(\(.\)|)))\t.*$
NSRegularExpression * regularExpression = [NSRegularExpression regularExpressionWithPattern:mutablePatternString
options:NSRegularExpressionAnchorsMatchLines
error:nil];
int rangeLocation = 0;
int rangeLength = [string length];
NSMutableArray * matches = [NSMutableArray array];
[regularExpression enumerateMatchesInString:string
options:0
range:NSMakeRange(rangeLocation, rangeLength)
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop){
[matches addObject:[string substringWithRange:result.range]];
}];
[mutablePatternString release];
// matches array is returned to the caller.
私の問題は、大きなテキスト ファイルを考えると、iPhone では十分な速度ではないことです。iPhone 4 では 8 ワードに 1.3 秒かかりますが、これはアプリケーションには長すぎます。次の既知の要因を考慮します。
• 3.2 MB のテキスト ファイルには、一致する単語がアルファベット順にリストされています。
• 検索する任意の単語の配列は、このメソッドに到達すると常にアルファベット順になります。
• 代替発音は、(1) ではなく、単語の後の括弧内の (2) で始まります。
• (2) がない場合、(3)、(4) またはそれ以上はありません。
• 代替発音が 1 つ存在することはまれで、平均して 8 回に 1 回発生します。さらに別の発音はさらにまれです。
正規表現または目的の C のいくつかの側面を改善することによって、この方法を最適化できますか? NSRegularExpression は既に十分に最適化されているため、別の Objective-C ライブラリや C で実行しようとする価値はないと思いますが、ここで間違っている場合はお知らせください。それ以外の場合は、パフォーマンスを改善するための提案に非常に感謝しています。これを任意の発音ファイルに一般化することを望んでいるので、事前にアルファベットの範囲を計算してより制限された検索を行うなどのソリューションから離れようとしています.
****編集****
2012 年 8 月 16 日までに提供されたすべての検索関連の回答に対する iPhone 4 のタイミングは次のとおりです。
dasblinkenlight の create NSDictionary アプローチhttps://stackoverflow.com/a/11958852/119717 : 5.259676 秒
https://stackoverflow.com/a/11957535/119717での Ωmega の最速の正規表現: 0.609593 秒
https://stackoverflow.com/a/11969602/119717での dasblinkenlight の複数の NSRegularExpression アプローチ: 1.255130 秒
https://stackoverflow.com/a/11970549/119717での私の最初のハイブリッド アプローチ: 0.372215 秒
https://stackoverflow.com/a/11970549/119717での私の 2 番目のハイブリッド アプローチ: 0.337549 秒
これまでのところ、私の回答の 2 番目のバージョンが最適です。検索関連の回答はすべて、私のバージョンで採用したアプローチに基づいているため、回答を最もよくマークすることはできません。それらはすべて非常に役立ち、私の回答は他の回答に基づいているだけです。私は多くのことを学び、私の方法は元の時間の 4 分の 1 で終わったので、これは非常に役に立ちました。