PDA

View Full Version : [SOLVED] - Am I misunderstanding how NSOrderedSame works?




chrono1081
Jan 22, 2012, 07:59 PM
Hi guys,

I'm re-learning my Objective-C (got my book back :D ) and I'm stuck on this one exercise. I can recreate it easy enough in C++ but not in Objective-C.

What its supposed to do is find every occurrence of a word in the proper names list found in /usr/share/dict/propernames that is also found in /usr/share/dict/words.

The example the book gives is "Glen" and "glen" since Glen is a persons name and also a noun.

I have tried all sorts of stuff and I keep getting weird results. I already checked to ensure that the arrays holding the proper names list and the words list are correct, but the comparisons are not working correctly and I'm not sure why.

Can someone with fresh eyes spot what I am doing wrong? Does NSOrderedSame not work how I think it works?

#import <Foundation/Foundation.h>

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

@autoreleasepool {

//Read in the file as a string
NSString *nameString = [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames"
encoding:NSUTF8StringEncoding
error:NULL];

NSString *wordString = [NSString stringWithContentsOfFile:@"/usr/share/dict/words"
encoding:NSUTF8StringEncoding
error: NULL];




//Break it into an array of strings
NSArray *names = [nameString componentsSeparatedByString:@"\n"];
NSArray *words = [wordString componentsSeparatedByString:@"\n"];

//This is where things go wrong
for(NSString *w in words)
{
for(NSString *n in names)
{
if([w caseInsensitiveCompare:n] == NSOrderedSame)
{
NSLog(@"%@ = w, %@ = n", w, n); //This comparison produces weird results!
}
}
}

}

return 0;
}


EDIT: I'm not sure if I found the problem or not, but it appears that the dictionary list contains proper names as well! It could have been correct the entire time 0_0! But I'll just leave it incase someone else can spot something wrong.

EDIT2: Oops I forgot my other comment. The results should be names like "Glen and glen" or "Brook" and brook" but everything is showing up so I'm pretty sure its because the common names are now in the dictionary list. I see Aaron is in the dictionary list.



chown33
Jan 22, 2012, 08:41 PM
1. Describe what you expected to happen.
2. Describe what actually happened.

"Weird results" is not a description of what actually happened. At least not in any useful way. Some example output would be useful.

You should also find a specific counter-example, such as the name Winston, that isn't in the words list. If you don't see Winston in your output, then you should reconsider "weird". (I only picked Winston because it's near the end when I cat'ed the propernames file. It also doesn't appear when I grep -i the words list.) In general, it's a good idea to run tests using small sample data that produces known results, before running it on the general data.


Also, this is a perfect case for NSSet. Read the personal names, convert to lower-case, then add to NSSet. Now you can read the list of words and much more quickly check whether it's a name or not.

You could get the same results by reading the words into an NSSet and then testing names, but look at the relative sizes of the sets and see which is smaller.

wc /usr/share/dict/words
wc /usr/share/dict/propernames

robvas
Jan 22, 2012, 09:01 PM
You can use a regular compare method for telling the difference between 'Glen' and 'glen'

If you want to tell which is greater, check for NSOrderedAscending and NSOrderedDescending.

[@"Glen" compare:@"glen"]

chrono1081
Jan 22, 2012, 10:32 PM
1. Describe what you expected to happen.
2. Describe what actually happened.

"Weird results" is not a description of what actually happened. At least not in any useful way. Some example output would be useful.

You should also find a specific counter-example, such as the name Winston, that isn't in the words list. If you don't see Winston in your output, then you should reconsider "weird". (I only picked Winston because it's near the end when I cat'ed the propernames file. It also doesn't appear when I grep -i the words list.) In general, it's a good idea to run tests using small sample data that produces known results, before running it on the general data.


Also, this is a perfect case for NSSet. Read the personal names, convert to lower-case, then add to NSSet. Now you can read the list of words and much more quickly check whether it's a name or not.

You could get the same results by reading the words into an NSSet and then testing names, but look at the relative sizes of the sets and see which is smaller.

wc /usr/share/dict/words
wc /usr/share/dict/propernames

Sorry for saying "weird!" I feel horrible doing so because I work in IT and hate when people don't give an accurate description and I just became that person:(.

I'm pretty sure at this point its a bug in the exercise. After some research it appears that the proper names list and the dictionary were merged. It was a simple exercise but I couldn't figure out why I was getting so many names hitting from the dictionary array and after some tests I found all the proper names were also in the dictionary :eek:

Thank you for the tip on NSSet though I'll have to look in to it. Its been awhile since I got to program in Objective-C so I am just now getting back in to it.

You can use a regular compare method for telling the difference between 'Glen' and 'glen'

If you want to tell which is greater, check for NSOrderedAscending and NSOrderedDescending.

[@"Glen" compare:@"glen"]

Thanks so much for the tip!