iOS iPhone如何按使用频率列出UTextView中的所有关键字?

iOS iPhone如何按使用频率列出UTextView中的所有关键字?,iphone,objective-c,ios,uitextview,keyword,Iphone,Objective C,Ios,Uitextview,Keyword,我得到了一个UITextView,任意长度的文本多达10000个字符。我需要解析此文本,提取所有关键字,并按使用频率列出它们,最常用的单词在顶部,下一个在底部,等等。操作完成后,我很可能会显示一个模态UITableView 我在想一个有效且有用的方法来做到这一点。我可以尝试使用分隔符分隔字符串,分隔符的形式为[空格、标点符号等]。 这会得到一个字符序列数组。 我可以将每个add序列添加为NSMutableDictionary键,并在看到该单词的另一个实例时增加其计数。然而,这可能会导致300-4

我得到了一个UITextView,任意长度的文本多达10000个字符。我需要解析此文本,提取所有关键字,并按使用频率列出它们,最常用的单词在顶部,下一个在底部,等等。操作完成后,我很可能会显示一个模态UITableView

我在想一个有效且有用的方法来做到这一点。我可以尝试使用分隔符分隔字符串,分隔符的形式为[空格、标点符号等]。 这会得到一个字符序列数组。 我可以将每个add序列添加为NSMutableDictionary键,并在看到该单词的另一个实例时增加其计数。然而,这可能会导致300-400个单词的列表,大多数单词的频率为1

有没有一个好的方法来实现我所描述的逻辑?我是否应该尝试按字母顺序对数组排序并尝试某种模糊逻辑匹配?是否有任何NSDataDetector或NSString方法可以为我完成此类工作

另外一个问题是:我如何提取诸如a、at、to、for等内容,而不在关键字列表中列出它们

如果我能看一看已经完成这项任务的示例项目,那就太好了

谢谢大家!

您可以使用来获取单词边界。对于计数,您可以按照建议使用NSMutableDictionary,或者使用NSCountedSet,这可能会稍微更有效一些

如果您对频率为1或其他阈值的单词不感兴趣,则必须在计算完所有单词后将其过滤掉

要忽略某些单词a、the、For…,您需要一个特定于文本语言的单词列表。包含两个链接,例如..

可以用来获取单词边界。对于计数,您可以按照建议使用NSMutableDictionary,或者使用NSCountedSet,这可能会稍微更有效一些

如果您对频率为1或其他阈值的单词不感兴趣,则必须在计算完所有单词后将其过滤掉


要忽略某些单词a、the、For…,您需要一个特定于文本语言的单词列表。包含两个链接,例如..

有许多方法可以做到这一点

您应该明确地将所有关键字添加到数组或其他集合对象中,并对其进行引用/迭代,以便搜索这些关键字和仅搜索这些关键字,并避免检查a、at、to、for等的出现情况

NSArray *keywords = [ add your keywords ];

NSString *textToSearchThrough = @" your text ";  // or load your text File here

- loop control statement here (like maybe fast enumerate), and inside this loop:
NSRange range = [textToCheckThrough rangeOfString:keywords[currentKeyword] 
                              options:NSCaseInsensitiveSearch];
if(range.location != NSNotFound) {
   // meaning, you did find it 
   // add it to a resultsArray, add 1 to this keyword's occurrenceCounter (which you must also declare and keep track of)
   // etc.
}

然后循环搜索结果数组,检查每个关键字的出现次数,清除出现次数为有很多方法可以做到这一点

您应该明确地将所有关键字添加到数组或其他集合对象中,并对其进行引用/迭代,以便搜索这些关键字和仅搜索这些关键字,并避免检查a、at、to、for等的出现情况

NSArray *keywords = [ add your keywords ];

NSString *textToSearchThrough = @" your text ";  // or load your text File here

- loop control statement here (like maybe fast enumerate), and inside this loop:
NSRange range = [textToCheckThrough rangeOfString:keywords[currentKeyword] 
                              options:NSCaseInsensitiveSearch];
if(range.location != NSNotFound) {
   // meaning, you did find it 
   // add it to a resultsArray, add 1 to this keyword's occurrenceCounter (which you must also declare and keep track of)
   // etc.
}
然后循环搜索结果数组,检查每个关键字的出现次数,清除出现次数为我最终使用了CFStringTokenizer。我不确定下面的桥接类型是否正确,但它似乎有效

-(void)listAllKeywordsInString:(NSString*)text
    {
        if(text!=nil)
        {
            NSMutableDictionary* keywordsDictionary = [[NSMutableDictionary alloc] initWithCapacity:1024];
            NSString* key = nil;
            NSLog(@"%@",text);

             NSLog(@"Started parsing: %@",[[NSDate date] description]);

            CFStringRef string =(__bridge CFStringRef)text; // Get string from somewhere

        CFStringTokenizerRef tokenizer = CFStringTokenizerCreate(kCFAllocatorDefault,  (__bridge_retained CFStringRef) text, CFRangeMake (0,CFStringGetLength((__bridge_retained CFStringRef)text)), kCFStringTokenizerUnitWord, CFLocaleCopyCurrent());

            unsigned tokensFound = 0; // or the desired number of tokens

            CFStringTokenizerTokenType tokenType = kCFStringTokenizerTokenNone;

            while(kCFStringTokenizerTokenNone != (tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)) ) {
                CFRange tokenRange = CFStringTokenizerGetCurrentTokenRange(tokenizer);
                CFStringRef tokenValue = CFStringCreateWithSubstring(kCFAllocatorDefault, string, tokenRange);

                // This is the found word
                key =(__bridge NSString*)tokenValue;

                //increment its count
                NSNumber* count = [keywordsDictionary objectForKey:key];
                if(count!=nil)
                {
                     [keywordsDictionary setValue:[NSNumber numberWithInt:1] forKey:key];
                }else {
                    [keywordsDictionary setValue:[NSNumber numberWithInt:count.intValue+1] forKey:key];
                }



                CFRelease(tokenValue);

                ++tokensFound;
            }
            NSLog(@"Ended parsing. tokens Found: %d, %@",tokensFound,[[NSDate date] description]);
            NSLog(@"%@",[keywordsDictionary description]);
            // Clean up
            CFRelease(tokenizer);

        }


    }
我最终选择了CFStringTokenizer。我不确定下面的桥接类型是否正确,但它似乎有效

-(void)listAllKeywordsInString:(NSString*)text
    {
        if(text!=nil)
        {
            NSMutableDictionary* keywordsDictionary = [[NSMutableDictionary alloc] initWithCapacity:1024];
            NSString* key = nil;
            NSLog(@"%@",text);

             NSLog(@"Started parsing: %@",[[NSDate date] description]);

            CFStringRef string =(__bridge CFStringRef)text; // Get string from somewhere

        CFStringTokenizerRef tokenizer = CFStringTokenizerCreate(kCFAllocatorDefault,  (__bridge_retained CFStringRef) text, CFRangeMake (0,CFStringGetLength((__bridge_retained CFStringRef)text)), kCFStringTokenizerUnitWord, CFLocaleCopyCurrent());

            unsigned tokensFound = 0; // or the desired number of tokens

            CFStringTokenizerTokenType tokenType = kCFStringTokenizerTokenNone;

            while(kCFStringTokenizerTokenNone != (tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)) ) {
                CFRange tokenRange = CFStringTokenizerGetCurrentTokenRange(tokenizer);
                CFStringRef tokenValue = CFStringCreateWithSubstring(kCFAllocatorDefault, string, tokenRange);

                // This is the found word
                key =(__bridge NSString*)tokenValue;

                //increment its count
                NSNumber* count = [keywordsDictionary objectForKey:key];
                if(count!=nil)
                {
                     [keywordsDictionary setValue:[NSNumber numberWithInt:1] forKey:key];
                }else {
                    [keywordsDictionary setValue:[NSNumber numberWithInt:count.intValue+1] forKey:key];
                }



                CFRelease(tokenValue);

                ++tokensFound;
            }
            NSLog(@"Ended parsing. tokens Found: %d, %@",tokensFound,[[NSDate date] description]);
            NSLog(@"%@",[keywordsDictionary description]);
            // Clean up
            CFRelease(tokenizer);

        }


    }

我有点不清楚。你想按频率列出所有关键词,但按频率排序的300-400个单词并不好,因为它们大多数只出现一次?我不清楚。您想按频率列出所有关键字,但按频率排序的300-400个单词并不好,因为它们大多数只出现一次?