Anagram / partial anagram detection algorithm find

2019-06-14 05:24发布

问题:

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);   
 }