代码之家  ›  专栏  ›  技术社区  ›  Jasarien

如何优化这个嵌套for循环?

  •  1
  • Jasarien  · 技术社区  · 16 年前

    如何优化这个嵌套for循环?

    程序应该遍历从Word文本文件创建的数组中的每个单词,如果超过8个字符,则将其添加到 goodWords 数组。但需要注意的是,我只希望根单词在goodwords数组中,例如:

    如果在数组中添加了问候语,则我不需要问候语、问候语或问候语等。

        NSString *string = [NSString stringWithContentsOfFile:@"/Users/james/dev/WordParser/word.txt" encoding:NSUTF8StringEncoding error:NULL];
        NSArray *words = [string componentsSeparatedByString:@"\r\n"];
        NSMutableArray *goodWords = [NSMutableArray array];
        BOOL shouldAddToGoodWords = YES;
    
        for (NSString *word in words)
        {
            NSLog(@"Word: %@", word);
    
            if ([word length] > 8)
            {
                NSLog(@"Word is greater than 8");
    
                for (NSString *existingWord in [goodWords reverseObjectEnumerator])
                {
                    NSLog(@"Existing Word: %@", existingWord);
                    if ([word rangeOfString:existingWord].location != NSNotFound)
                    {
                        NSLog(@"Not adding...");
                        shouldAddToGoodWords = NO;
                        break;
                    }
                }
    
                if (shouldAddToGoodWords)
                {
                    NSLog(@"Adding word: %@", word);
                    [goodWords addObject:word];
                }
            }
    
            shouldAddToGoodWords = YES;
        }
    
    3 回复  |  直到 16 年前
        1
  •  3
  •   Dave DeLong    16 年前

    像这样的东西怎么样?

    //load the words from wherever
    NSString * allWords = [NSString stringWithContentsOfFile:@"/usr/share/dict/words"];
    //create a mutable array of the words
    NSMutableArray * words = [[allWords componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] mutableCopy];
    //remove any words that are shorter than 8 characters
    [words filterUsingPredicate:[NSPredicate predicateWithFormat:@"length >= 8"]];
    //sort the words in ascending order
    [words sortUsingSelector:@selector(caseInsensitiveCompare:)];
    
    //create a set of indexes (these will be the non-root words)
    NSMutableIndexSet * badIndexes = [NSMutableIndexSet indexSet];
    //remember our current root word
    NSString * currentRoot = nil;
    NSUInteger count = [words count];
    //loop through the words
    for (NSUInteger i = 0; i < count; ++i) {
        NSString * word = [words objectAtIndex:i];
        if (currentRoot == nil) {
            //base case
            currentRoot = word;
        } else if ([word hasPrefix:currentRoot]) {
            //word is a non-root word.  remember this index to remove it later
            [badIndexes addIndex:i];
        } else {
            //no match. this word is our new root
            currentRoot = word;
        }
    }
    //remove the non-root words
    [words removeObjectsAtIndexes:badIndexes];
    NSLog(@"%@", words);
    [words release];
    

    这在我的机器上运行非常快(2.8GHz Mbp)。

        2
  •  2
  •   Aryabhatta    16 年前

    Trie 似乎适合你的目的。它类似于散列,对于检测给定字符串是否是已看到字符串的前缀非常有用。

        3
  •  1
  •   Brock Woolf    16 年前

    我用过 NSSet 以确保一次只添加一个单词的副本。如果 NSET 不包含它。然后检查新单词是否是已添加单词的子字符串,如果为真,则不会添加新单词。它也不区分大小写。

    我所写的是代码的重构。它可能不会快得多,但如果您想在搜索已经添加到树中的单词时更快地搜索树数据结构,那么您确实需要它。

    看一看 RedBlack Trees B-Trees .

    词组

    objective
    objectively
    cappucin
    cappucino
    cappucine
    programme
    programmer
    programmatic
    programmatically
    

    源代码

    - (void)addRootWords {
    
        NSString        *textFile = [[NSBundle mainBundle] pathForResource:@"words" ofType:@"txt"];
        NSString        *string = [NSString stringWithContentsOfFile:textFile encoding:NSUTF8StringEncoding error:NULL];
        NSArray         *wordFile = [string componentsSeparatedByString:@"\n"];
        NSMutableSet    *goodWords = [[NSMutableSet alloc] init];
    
        for (NSString *newWord in wordFile)
        {
            NSLog(@"Word: %@", newWord);
            if ([newWord length] > 8)
            {
                NSLog(@"Word '%@' contains 8 or more characters", newWord);
                BOOL shouldAddWord = NO;
                if ( [goodWords containsObject:newWord] == NO) {
                    shouldAddWord = YES;
                }
                for (NSString *existingWord in goodWords)
                {
                    NSRange textRange = [[newWord lowercaseString] rangeOfString:[existingWord lowercaseString]];
                    if( textRange.location != NSNotFound ) {
                        // newWord contains the a substring of existingWord
                        shouldAddWord = NO;
                        break;
                    }
                    NSLog(@"(word:%@) does not contain (substring:%@)", newWord, existingWord);
                    shouldAddWord = YES;
                }
                if (shouldAddWord) {
                    NSLog(@"Adding word: %@", newWord);
                    [goodWords addObject:newWord];
                }
            }
        }
    
        NSLog(@"***Added words***");
        int count = 1;
        for (NSString *word in goodWords) {
            NSLog(@"%d: %@", count, word);
            count++;
        }
    
        [goodWords release];
    }
    

    输出:

    ***Added words***
    1: cappucino
    2: programme
    3: objective
    4: programmatic
    5: cappucine