0

I have an Array full of PhRecords. For simplicity sake, let us consider the structure of object is as follows:

@interface PhRecord : NSObject

@property (nonatomic, strong) NSArray *PhName; //Person's name
@property (nonatomic, strong) NSArray *PhNumbers; //Person will have 2/3 contact numbers
@property (nonatomic, strong) NSArray *PhTypes; //The types of the contact numbers

@end

There is a property in my class which goes through the phone book and collects the names and phone numbers in an array in the format specified above. Let's say the array is the following

@property (nonatomic, strong) NSArray *allContacts;

Also, I have method to get all contacts as PhRecords with the following method

- (NSArray *)getAllContacts;

I have a method where if I give the contact number, it will find the name and type of the contact.

//Assume that both string1 and string2 don't have (,),*,#,+ and "<white space>"
- (void)findContactByPhoneNumber:(NSString *)phNum {
    NSString *string1 = phNum;
    NSArray *contacts = [self getAllContacts];
    for(SDPhoneRecord *record in contacts) {
        for(int j=0;j<record.PhNumbers.count;j++) {
            NSString *string2 = [[record.PhNumbers objectAtIndex:j];
            if([string2 rangeOfString:string1].location!=NSNotFound) {
                NSLog(@"Name:%@,Type:%@",record.PhName,[record.PhTypes objectAtIndex:j];
            }
        }
    }
}

As you can see, this search has time complexity of O(n^2). Is it possible to do a O(1) lookup? If I have to use predicates, how can I use them with this kind of requirement where a "range" of string has to be compared with the string passed argument?

thandasoru
  • 1,558
  • 2
  • 15
  • 41
  • It is possible to get close to O(n). All you need to do is use an NSDictionary or other efficiently searched object for you PhNumbers object. – Hot Licks Dec 25 '13 at 14:21
  • Ok, I'll modify the data structure accordingly. Many thanks for the suggestion! – thandasoru Dec 25 '13 at 14:40

2 Answers2

3

To improve the "big O" you need to eliminate loops, not simply hide them. This generally implies using some sort of "look at" mechanism, vs a "look up" mechanism -- a mechanism that uses, eg, a hash table to locate item. The main such mechanism in Objective-C is the NS(Mutable)Dictionary, which internally contains a hash table.

In some cases it's possible to employ properties of the data to improve search efficiency, but absent that the hash table is usually the best (and most general) approach.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
0

Use the NSArray objectsPassingTest where the test is if the phone number attribute is equal to the provided string

Garrett
  • 5,580
  • 2
  • 31
  • 47
  • Equality can't be the relation. For example, I might provide 1234567 but the contact might have 001-1234567. Can I check range with objectsPassingTest? – thandasoru Dec 25 '13 at 14:15
  • Using objectsPassingTest, et al, will not improve the "big O" of the algorithm, just hide part of it (and generally be somewhat less efficient than the straight-forward loop). – Hot Licks Dec 25 '13 at 14:23