Although not the most fast solution to this challenge, this ‘nested if’ does not use information that is yet to be presented in the book. Although using advanced concepts to solve these challenges makes for an interesting learning exercise, I would rather learn step-by-step as guided by the authors’ expertise.
//
// main.m
// InterestingNames (nested if)
//
// Created by James Macak on 3/19/15.
// Copyright (c) 2015 James Macak. All rights reserved.
//
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// Read in a file as a huge string, ignoring the possibility of an error
NSString *nameString = [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames"
encoding:NSUTF8StringEncoding
error:NULL];
// Break it into an array of strings
NSArray *names = [nameString componentsSeparatedByString:@"\n"];
// Read in a file as a huge string, ignoring the possibility of an error
NSString *wordString = [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
encoding:NSUTF8StringEncoding
error:NULL];
// Break it into an array of strings
NSArray *wordsList = [wordString componentsSeparatedByString:@"\n"];
// Find number of items in the arrays
NSUInteger wordsCount = [wordsList count];
// The next four lines provide some info about the lists but are not essential
NSUInteger namesCount = [names count];
NSLog(@"The count for the array 'names' is %lu and for 'wordsList' is: %lu", namesCount, wordsCount);
NSLog(@"The first and last items in 'names' are %@ and %@", names[0],names[namesCount - 2]);
NSLog(@"The first and last items in 'wordsList' are %@ and %@", wordsList[0],wordsList[wordsCount - 2]);
// Setup a counter for successful matches
long matchesCount = 0;
// Setup an object to hold the start time of the for loop
NSDate *startTime = [NSDate date];
// Regarding the following for loop:
// The first 'if' will be true only when two adjoining words in the array 'wordsList' are case insensitive matches
// Based on what we know of the words list, these matches are the only words that might also be in the names list
// The second (nested) 'if' is true if the first or the second of these adjoining words are contained in the 'names' array
//
// NOTE: The second part of the 'or' is not needed if we assume the first of the adjoining words is capitalized
//
// The improved run time (which is at least 15x) comes from performing the 'containsObject' test
// on the much shorter 'names' array which has 1309 objects, vs. the 235,887 objects in the 'wordList' array
for (int i = 0; i < wordsCount - 3; i++) {
if ([[wordsList[i] lowercaseString] isEqual: [wordsList[i+1] lowercaseString]]) {
// if ([names containsObject:wordsList[i]]) { // see the for loop notes above
if (([names containsObject:wordsList[i]]) || ([names containsObject:wordsList[i+1]])){
NSLog(@"Found match: %@ and %@", wordsList[i], wordsList[i+1]);
matchesCount++;
}
}
}
// Save the end time of the for loop
NSDate *endTime = [NSDate date];
// Print the total number of proper names matches in the regular words list
NSLog(@"Total matches equals %lu", matchesCount);
// Determine and print the run time of the for loop
double intervalSeconds = [endTime timeIntervalSinceDate:startTime];
NSLog(@"The runtime of the for loop was %.2f seconds", intervalSeconds);
}
return 0;
}
Output:
2015-03-19 22:36:33.711 InterestingNames (nested if)[89920] The count for the array ‘names’ is 1309 and for ‘wordsList’ is: 235887
2015-03-19 22:36:33.712 InterestingNames (nested if)[89920] The first and last items in ‘names’ are Aaron and Yvonne
2015-03-19 22:36:33.712 InterestingNames (nested if)[89920] The first and last items in ‘wordsList’ are A and Zyzzogeton
2015-03-19 22:36:33.718 InterestingNames (nested if)[89920] Found match: Al and al
2015-03-19 22:36:33.718 InterestingNames (nested if)[89920] Found match: Alan and alan
…
…
2015-03-19 22:36:34.246 InterestingNames (nested if)[89920] Found match: Wolf and wolf
2015-03-19 22:36:34.246 InterestingNames (nested if)[89920] Found match: Woody and woody
2015-03-19 22:36:34.250 InterestingNames (nested if)[89920] Total matches equals 293
2015-03-19 22:36:34.250 InterestingNames (nested if)[89920] The runtime of the for loop was 0.54 seconds
Program ended with exit code: 0
As noted in the code comments, this is a pretty fast solution as compared to others that use NSArray and NSString programming.
I’d appreciate hearing your comments, critiques and suggestions for improvement.
Cheers.