题目
- /usr/share/dict/propernames文件保存着常见专有名词,/usr/share/dict/words文件保存着常用的单词及专有名词,其中专有名词都是首字母大写。这些文件是在Mac上预装好了的。
- 编写程序,找出既是专有名词又是单词的字符串,即同时存在于专有名词表单和常见名词表单(以小写显示)中存在的字符串。
分析
首先/usr/share/dict/words文件中既保存了常用单词又保存了专有名词,题目要求是找出同时存在于
/usr/share/dict/propernames文件
和/usr/share/dict/words文件中以小写显示的常见名词表单
,后者即需要去除首字母大写的这些专有名词。
- 读入文件
- 过滤words文件中的专有名词
- 找出同时存在于二者的单词
代码
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
//读入文件并将数据保存在字符串中
NSString *nameString=[NSString stringWithContentsOfFile:@"/usr/share/dict/propernames" encoding:NSUTF8StringEncoding error:NULL];
NSString *wordString=[NSString stringWithContentsOfFile:@"/usr/share/dict/words" encoding:NSUTF8StringEncoding error:NULL];
//根据‘\n’分割字符串,保存至数组
NSArray *names=[nameString componentsSeparatedByString:@"\n"];
NSArray *words=[wordString componentsSeparatedByString:@"\n"];
//删除掉words表单中以大写字母开头的词(专有名词),结果放在mutableWords中
NSMutableArray *mutableWords = [[NSMutableArray alloc] init];
for(int i = 0; i < words.count; ++i){
if([words[i] length] > 0){
unichar ch = [words[i] characterAtIndex:0];
if(!(ch >= 'A' && ch <='Z')){
//不以大写字母开头则放入候选数组mutableWords中
[mutableWords addObject:words[i]];
}
}
}
words = [mutableWords copy];
//根据两份表单长度选择排序哪一份表单
NSArray *longStrList;
NSArray *shortStrList;
if(names.count>words.count){
longStrList=names;
shortStrList=words;
}else{
longStrList=words;
shortStrList=names;
}
//排序较短表单
shortStrList=[shortStrList sortedArrayUsingSelector:@selector(compare:)];
//遍历较长表单
NSUInteger shortSize=shortStrList.count;
for(NSString *str in longStrList){
//在排序表单中进行二分查找
NSUInteger low=0,high=shortSize-1;
while(low<high){
NSUInteger mid=(low+high)/2;
//不区分大写小写
NSComparisonResult result= [str caseInsensitiveCompare:[shortStrList objectAtIndex:mid]];
if(result==NSOrderedAscending){
//str更小
high=mid-1;
}else if(result==NSOrderedDescending){
//str更大
low=mid+1;
}else{
//已经找到相同的字符串
NSLog(@"here is:%@",str);
break;
}
}
}
}
return 0;
}
其他
- “删除掉words表单中以大写字母开头的词(专有名词)”这一步骤能否尝试使用NSPredicate来过滤?