Interesting Names Solution


#1

[code]#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

@autoreleasepool
{

    // Read in proper names file (ignoring the possibility of an error)
    NSString *properNamesString =
    [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames"
                              encoding:NSUTF8StringEncoding
                                 error:nil];
    
    // Read in words file (ignoring the possibility of an error)
    NSString *wordsString =
    [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
                              encoding:NSUTF8StringEncoding
                                 error:nil];
    
    // Create empty mutable array to store match name and word
    NSMutableArray *matchNames = [NSMutableArray array];
    
    // Lower case all the proper names
    // Only interested in proper names that have matched words
    properNamesString = [properNamesString lowercaseString];
    NSArray *properNames = [properNamesString componentsSeparatedByString:@"\n"];
    NSArray *words = [wordsString componentsSeparatedByString:@"\n"];
    
    // Get start time
    NSDate *startTime = [NSDate date];
    
    // Loop through proper names
    int counter = 0;
    for (NSString *name in properNames)
    {
        // Loop through words to find if there is a match with a proper name
        for (int i = counter; i < [words count]; i++)
        {
            if ([name isEqualToString:[words objectAtIndex:i]])
            {
                counter = i;
                [matchNames addObject:name];
                break;
            }
        }
        
        // This loop takes a slightly longer time

// for (NSString *word in words)
// {
// if ([name isEqualToString:word])
// {
// [matchNames addObject:name];
// break;
// }
// }
}

    // Get end time
    NSDate *endTime = [NSDate date];
    
    // Log out matched name list
    NSLog(@"The name list is:");
    for (NSString *s in matchNames)
        NSLog(@"%@", s);
    // Log out matched name list count
    NSLog(@"Count: %lu", [matchNames count]);
    
    // Log out time lapse for the loop
    double timeLapse = [endTime timeIntervalSinceDate:startTime];
    NSLog(@"Time taken: %.2fs", timeLapse);
    
}

return 0;

}[/code]

Hi above is my code. I ran it and the time taken is about 9.57s.
My name count is 294.
Will like to check if anyone has the same values as me.


#2

My name count was also 294. What troubled me is that it took 11.60 seconds compared to your 9.57 seconds!

After reviewing your code, I found what was causing my sluggishness.

Originally, I had the lowercaseString method take place in the for loop:

for (NSString *n in names) {
            if ([words containsObject:[n lowercaseString]]) {
                NSLog(@"Found one: %@", n);
                totalMatches++;
            }
        }

So I moved that method out of the for loop and into its own statement before the for loop occurs:

namesString = [namesString lowercaseString];

Now the code completes in 3.50 seconds! It’s amazing how the placement of one simple method significantly affects performance.