Challenge 2 - My solution


#1

Here is my solution to the NSArray 2nd challenge …

NOTE: This assumes that both lists are sorted into alphabetical order prior to the search taking place.

#import <Foundation/Foundation.h>

void SearchList(NSArray *sList, NSArray *fList, NSMutableArray *mList);

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        // read 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 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 *words = [wordString componentsSeparatedByString:@"\n"];
        
        // count 'em
        NSLog(@"Count of names %lu", [names count]);
        NSLog(@"Count of words %lu", [words count]);
  
        // define the matches array
        NSMutableArray *matchList = [NSMutableArray array];
        
        // start time of processing
        NSDate *startTime = [NSDate date];
        
        // search word list for name list
        SearchList(words, names, matchList);
        
        // list out the matched names
        for (NSString *m in matchList)
        {
            NSLog(@"%@", m);
        }
        
        NSLog(@"MatchList count: %lu", [matchList count]);

        NSDate *endTime = [NSDate date];
        double timeLapsed = [endTime timeIntervalSinceDate:startTime];
        
        NSLog(@"S: %@", startTime);
        NSLog(@"F: %@", endTime);
        NSLog(@"E: %.2f", timeLapsed);
    }
    
    return 0;
}

void SearchList(NSArray *sList, NSArray *fList, NSMutableArray *mList)
{
    // search supplied list for matches (regular words only)
    // sList contains the list to be searched
    // fList contains the list to be found
    // mList contains any matches
    
    // sList index
    long idx = 0;
    
    for (NSString *i in fList)
    {
        // compare entries
        
        while ([i caseInsensitiveCompare:[sList objectAtIndex:idx]] == NSOrderedDescending)
        {
            // not matched - need to bump up to next sList item
            idx++;
        }
        while ([i caseInsensitiveCompare:[sList objectAtIndex:idx]] == NSOrderedSame)
        {
            // matched pair - only interested in regular word matches
            if (![i compare:[sList objectAtIndex:idx]] == NSOrderedSame)
            {
                [mList addObject:i];
            }
            // bump up to the next sList item
            idx++;
        }
        // bump up to next fList item.
    }
    
}

I’d appreciate some critique, good bad or indifferent, please.

I decided to put the search into a function, you never know I might require it that way one day.

My processing is basically, work through the name list, searching for the current name in the word list.

If the word list item is less than the name item, then bump up to the next word item and check again.

If the word item matches (case insensitive), check if a case sensitive match has occurred, if so then not interested, otherwise I have a match - add this to the match list and bump up to next word item, might be another match.

Otherwise, the name list item has not been matched, bump up to the next name item.


#2

[quote]I’d appreciate some critique, good bad or indifferent, please.
[/quote]
If the file names could be entered as command-line arguments, testing the program with different files would be easier.

//  CmdArgs.m - Get command line arguments from NSUserDefaults
//

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    @autoreleasepool {
                
        NSUserDefaults *UD = [NSUserDefaults standardUserDefaults];
        
        // For example: ./CmdArgs -BB FooBar.log -AA 7.3
  
        NSLog (@"AA: %@", [UD valueForKey:@"AA"]);
        NSLog (@"BB: %@", [UD valueForKey:@"BB"]);

    }
    return 0;
}

#3

Thanks for this Ibex10 - useful to know, I’ll keep a note of it.

I’ve not got to that part of the book yet, if it is in there. Early days yet, although I’m a 30+ year mainframe coder:)