最近做iphone项目,需要做通讯录,地名按拼音排序,在网上搜索n多资料寻找解决方案,综合多方资料,最终形成如下方案:
所需工具:一个拼音表(如需要,可联系我),
过程:
1、对拼音表排序,得到一个包含“十六进制编码 拼音”格式的单元的按汉字十六进制编码排序的数组
/****************************汉字转16进制***********************************/
- (NSString *) Chinese_To_Hex:(NSString *)ChineseStr
{
//中英文数字参杂在一起也可以转换
NSMutableString * ret = [[NSMutableString alloc] init];
NSInteger length = [ChineseStr length];
for (NSInteger i =0; i < length; i++) {
[ret appendFormat:@"%x", [ChineseStr characterAtIndex:i]];
}
return [ret autorelease];
}
/****************************汉字转16进制***********************************/
- (void) testConvert
{
/*
NSString * strChinese = @"中国共浐党万岁";
//4e2d 56fd 5171 6d50 515a 4e07 5c81
NSString * strTemp = [self Chinese_To_Hex:strChinese];
//Chinese_To_Hex()此函数转的是GB码
NSLog(@"%@", strTemp);
*/
[self getPinyinBiao];
}
-(void) getPinyinBiao
{
NSString *tmp;
NSArray *lines; /*将文件转化为一行一行的*/
NSString * path = [[NSBundle mainBundle] pathForResource:@"tn_pinyin" ofType:nil];
NSString * content = [[NSString alloc] initWithContentsOfFile:path];
lines = [content componentsSeparatedByString:@"\n"];
[content release];
NSEnumerator *nse = [lines objectEnumerator];
// 读取<>里的内容
NSMutableDictionary * pinyinDict = [[[NSMutableDictionary alloc] init] autorelease];
while(tmp = [nse nextObject]) {
if (tmp && ![tmp isEqual:[NSNull null]]) {
NSLog(@"%@", tmp);
NSArray * tmpArr = [tmp componentsSeparatedByString:@" "];
if ([tmpArr count] >1) {
[pinyinDict setValue:[tmpArr objectAtIndex:0] forKey:tmp];
}
}
}
//[lines release];
NSArray * keyValuePairSortedByValue = [pinyinDict keysSortedByValueUsingSelector:@selector(compare:)];
NSString * savePath = [NSHomeDirectory() stringByAppendingPathComponent:@"tmp/pinyin.plist"];
NSLog(@"--- savepath: %@", savePath);
[keyValuePairSortedByValue writeToFile:savePath atomically:YES];
NSLog(@"done");
}
@implementation NSString (md5)
- (NSString *) md5
{
const char *cStr = [self UTF8String];
unsigned char result[16];
CC_MD5( cStr, strlen(cStr), result ); // This is the md5 call
return [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];
}
-(NSComparisonResult)pinYinCompare:(NSString *)other
{
NSString * myPinyin = [self hanziToPinYin];
NSString * otherPinyin = [other hanziToPinYin];
//TNLog(@"pinyin : %@ -> %@, %@ -> %@", self, myPinyin, other, otherPinyin);
return [myPinyin compare:otherPinyin];
}
- (NSString *) hanziToPinYin
{
NSString * pinyin = nil;
NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init];
NSMutableString * mStr = [[NSMutableString alloc] init];
for (NSInteger i = 0; i < self.length; i++) {
NSRange range = NSMakeRange(i, 1);
NSString * pstr = [[self substringWithRange:range] getPinYinOfSingleHanzi];
if (pstr != nil) {
[mStr appendString:pstr];
}
}
if (mStr.length > 0) {
pinyin = [mStr retain];
}else {
pinyin = [self retain];
}
[mStr release];
[pool1 release];
return [pinyin autorelease];
}
- (NSString *) getPinYinOfSingleHanzi
{
if ([self characterAtIndex:0] < 128) {
//return self;
}
NSString * returnString = nil;
NSArray * hanziToPinyin = [[Func getPinyinList] retain];
//URLEncode
//NSString *encodeStr = (NSString *) CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self, NULL, NULL, kCFStringEncodingGB_18030_2000);
//Hex(GB)
NSString * lowerCaseEncode = [[NSString alloc] initWithFormat:@"%x", [self characterAtIndex:0]];
NSString * encodeStr = [lowerCaseEncode uppercaseString];
[lowerCaseEncode release];
//TNLog(@"--- pinyin for : %@, encodestring: %@", self, encodeStr);
NSInteger low = 0;
NSInteger high = [hanziToPinyin count] - 1;
NSInteger middle = 0;
do{
middle = ((int)(low + high))/2;
NSString * keyValuePair = [hanziToPinyin objectAtIndex:middle];
NSArray * pinyinPair = [keyValuePair componentsSeparatedByString:@" "];
NSComparisonResult compareResult = [encodeStr compare:[pinyinPair objectAtIndex:0]];
switch (compareResult) {
case NSOrderedAscending:
high = middle - 1;
break;
case NSOrderedSame:
returnString = [[pinyinPair objectAtIndex:1] retain];
break;
case NSOrderedDescending:
low = middle + 1;
break;
default:
break;
}
if (returnString) {
break;
}
}while (low <= high);
[hanziToPinyin release];
if (returnString == nil) {
[returnString release];
returnString = [self retain];
}
return [returnString autorelease];
}