我得到了UITextView
一个任意长度的文本(最多10000个字符)。我需要解析这个文本,提取所有关键字,并按照使用频率列出它们,最常用的单词在顶部,下一个,等等。我很可能在操作完成后呈现模态UITableView。
我正在考虑一种高效且有用的方法。我可以尝试使用[空格,标点符号等]形式的分隔符来分隔字符串。
这让我获得了一系列字符序列。
我可以将每个添加序列添加为NSMutableDictionary
键,并在看到该单词的另一个实例后递增其计数。但是,这可能会产生300-400个字的列表,大多数频率为1.
有没有一种很好的方法来实现我所描述的逻辑?我应该尝试按字母顺序对数组进行排序并尝试某种“模糊”逻辑匹配吗? 是否有任何NSDataDetector或NSString方法可以为我做这种工作?
另一个问题是:我如何提取a,at,to,for等内容,而不是在关键字列表中列出?
如果我可以查看已经完成此任务的示例项目,那将会很棒。
谢谢!
答案 0 :(得分:2)
您可以使用CFStringTokenizer
来获取字边界。对于计数,您可以按照建议使用NSMutableDictionary
,也可以使用效率稍高的NSCountedSet
。
如果您对频率为1(或其他阈值)的单词不感兴趣,则必须在计算所有单词后将其过滤掉。
要忽略某些单词(a,the,for ...),您需要一个特定于文本语言的单词列表。 Wikipedia article on stop words包含几个链接,例如this CSV file
答案 1 :(得分:2)
有很多方法可以做到这一点。
您绝对应该将所有关键字添加到数组(或其他集合对象)并引用它/遍历它,以便您搜索这些关键字并仅搜索这些关键字(并且避免检查a,at,to的出现次数) ,等等。)
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.
}
然后循环遍历结果数组,检查每个关键字的出现次数,清除那些出现次数为< minOccurrenceCount,并从最高到最低排序。
答案 2 :(得分:0)
我最终选择了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);
}
}