My solution to challenge 2 (single for loop)


#1

I’ve tried both the solutions that are mentioned in the forum and the one below. The one below seems to run quite a bit faster, with the same results:

        int number = 0;
        
        // Read names and words
        NSString *nameString = [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames"
                                                         encoding:NSUTF8StringEncoding
                                                            error:NULL];
        NSString *wordString = [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
                                                         encoding:NSUTF8StringEncoding
                                                            error:NULL];
        NSArray *names = [nameString componentsSeparatedByString:@"\n"];
        NSArray *words = [wordString componentsSeparatedByString:@"\n"];
        
        // Per name:
        for (NSString *n in names) {
            
            // Check occurence of n in words
            if ([words containsObject:n.lowercaseString]) {
                NSLog(@" The proper name %@ is also a word", n);
                number++;
            }
        }
        
//        NSLog(@"total number: %d (%lul / %lul)", number, [names count], [words count]);

Found the containsObject in the documentation.


#2

In the output all names are also words ?

.
.
“2014-08-20 12:57:16.586 namesSearch[848:303] The proper name Rick is also a word”
“2014-08-20 12:57:16.634 namesSearch[848:303] The proper name Rob is also a word”
.
.
“2014-08-20 12:57:18.496 namesSearch[848:303] The proper name Tolerant is also a word”
.
.


#3

Yes they are. I was surprised as well. But if you look at “rick” for example you see in the snippet from the words file it appears in the file as “rick” and “Rick”…

...
ricinolic
Ricinulei
Ricinus
ricinus
Rick
rick
rickardite
ricker
ricketily
...

#4

[quote][code] …
// Per name:
for (NSString *n in names) {

        // Check occurence of n in words
        if ([words containsObject:n.lowercaseString]) {
            NSLog(@" The proper name %@ is also a word", n);
            number++;
        }
    }
    ...[/code][/quote]

Did you ever wonder why?

NSArray does not arrange objects in its store naively in a linear sequence, but it uses a hash function to arrange the objects in its store, and containsObject: method uses the hash function to search for objects.

[Become a competent programmer faster than you can imagine: pretty-function.org]


#5

[quote=“de1lub”]I’ve tried both the solutions that are mentioned in the forum and the one below. The one below seems to run quite a bit faster, with the same results:

        int number = 0;
        
        // Read names and words
        NSString *nameString = [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames"
                                                         encoding:NSUTF8StringEncoding
                                                            error:NULL];
        NSString *wordString = [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
                                                         encoding:NSUTF8StringEncoding
                                                            error:NULL];
        NSArray *names = [nameString componentsSeparatedByString:@"\n"];
        NSArray *words = [wordString componentsSeparatedByString:@"\n"];
        
        // Per name:
        for (NSString *n in names) {
            
            // Check occurence of n in words
            if ([words containsObject:n.lowercaseString]) {
                NSLog(@" The proper name %@ is also a word", n);
                number++;
            }
        }
        
//        NSLog(@"total number: %d (%lul / %lul)", number, [names count], [words count]);

Found the containsObject in the documentation.[/quote]

Output:
total number: 294 (1309 / 235887)


#6

Good solution. I added this part to the if statement because I was getting an empty @"" for the last iteration.

This was my output without the addition:

Al is both a name and a word. 1 Alan is both a name and a word. 2 Alf is both a name and a word. 3 ... Woody is both a name and a word. 293 is both a name and a word. 294

And here is the output with my modification to the if statement

Al is both a name and a word. 1 Alan is both a name and a word. 2 Alf is both a name and a word. 3 ... Woody is both a name and a word. 293

Here is my modified if statement:


#7

Thanks for sharing. That is MUCH quicker!