问题
I've written the following method to find out whether a long word contains a shorter word, and the order in which I pass the letters appears to effect the outcome.
I've noticed that if I feed it absconds
and bassy
it correctly reports NO
, but if I alphabetize the letters and give it abcdnoss
and abssy
, it gives YES
. I'm not too sure why this is – can anyone spot the issue?
- (BOOL) does: (NSString* ) longWord contain: (NSString *) shortWord {
while([longWord length] > 0 && [shortWord length] > 0) {
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString: [shortWord substringToIndex: 1]];
if ([longWord rangeOfCharacterFromSet: set].location == NSNotFound) {
return NO;
}
longWord = [longWord substringFromIndex: [longWord rangeOfCharacterFromSet: set].location+1];
shortWord = [shortWord substringFromIndex: 1];
}
return YES;
}
回答1:
The problem with your algorithm is that this line doesn't work:
longWord = [longWord substringFromIndex: [longWord rangeOfCharacterFromSet: set].location+1];
If the first letter you search is at the end of the long word, then long word becomes an empty string, and you jump out of your loop to YES.
I would use a different algorithm, like this. I think it's easier to see what's going on, and so less prone to errors:
- (BOOL) does: (NSString* ) longWord contain: (NSString *) shortWord {
NSMutableString *longer = [longWord mutableCopy];
for (int i = 0; i<shortWord.length; i++) {
NSString *letter = [shortWord substringWithRange:NSMakeRange(i, 1)];
NSRange letterRange = [longer rangeOfString:letter];
if (letterRange.location != NSNotFound) {
[longer deleteCharactersInRange:letterRange];
}else{
return NO;
}
}
return YES;
}
回答2:
- (BOOL) does: (NSString* ) longWord contain: (NSString *) shortWord
{
return ([longWord rangeOfString:shortWord].location != NSNotFound);
}
来源:https://stackoverflow.com/questions/13462367/anagram-partial-anagram-detection-algorithm-finds-incorrect-answers