1

我有一个从通讯簿中检索到的联系人列表,存储在 MutableArray 联系人列表中。每个联系人都是一个对象,具有“contactName、contactImage.... etc”等属性。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
    //getAllContacts is a method which returns a Mutable array of Objects
    self.contactList = [NSMutableArray arrayWithArray:[instance getAllContacts]];

    //groupLetterToLoad could be "DEF"
    for(int j=0; j<self.groupLetterToLoad.length;j++) { 
        //1st iteration D, 2nd iteration E and 3rd iteration F
        NSString *testChar = [NSString stringWithFormat:@"%c",[self.groupLetterToLoad characterAtIndex:j]];
        //check D,E,F with contact name property's first letter of the contact list array
        for(int i=0;i<self.contactList.count;i++) {
            NSString *firstChar =[[[self.contactList objectAtIndex:i] contactName] substringToIndex:1];
            if([testChar isEqualToString: firstChar]) {
                pos=i; //retrieve the index of the matched position
                break;
            }
        }
        if(pos!=-1) break;
    }
});

现在这有两个for循环(时间O(n ^ 2))。这里的缺点是,如果groupLetterToLoad是“WXYZ”,那么比较将从W和A开始到W和Z..我该如何优化它?

4

2 回答 2

2

contactName如果可以避免每次搜索时都进行排序(提示:保持[instance getAllContacts]排序),那么对数组进行排序并执行半间隔搜索将大大降低您的复杂性。

http://rosettacode.org/wiki/Binary_search#Objective-C - 这是一个起点。你可以compare:用你的第一个字符比较替换。

于 2013-10-01T09:03:02.560 回答
0

这不是算法改进,但您处理字符的方式可能是最慢的方式。如果您的组字母确实是您所指出的 ASCII 字母,请尝试此操作(我在答案中包含“if”,因为对非 ASCII 进行正确比较确实最好留给 NSString):

1) 不要使用 -substringToIndex 来获取第一个字符,而是使用 -characterAtIndex:0 并存储一个 unichar

2)不要使用 +stringWithFormat:@"%c" 来制作单个字符串,只需使用 -characterAtIndex: 并将其存储在 unichar

3) 不要使用 -isEqualToString:,而是在 unichars 上使用 ==

无关,我对此的线程安全性持怀疑态度。您访问的 self 和 instance 上的所有这些属性真的没有在任何其他队列或线程上访问吗?

于 2013-10-01T08:24:04.303 回答