目标C - 重复的排列计算

时间:2010-07-19 04:31:21

标签: objective-c recursion permutation

我似乎无法真正想到解决这个问题的方法,因某些原因无法让我的大脑围绕它。我试图解决的问题是:

对于拼图求解器类型算法,我将重复的字母作为NSString的子字符串。假设用户输入“RBEEEIOOUUU” 我只是从它们的字符串中提取重复项,并希望看到这些重复项的每个可能的组合,而不是在字符串中的位置,而只是通过改变重复计数。 (对于这个问题,位置并不重要,我稍后会按字母顺序排列..)

所以,给定字符串EEEOOUUU, 我想根据实际上改变重复项来推导出一组所有可能的字符串组合,

在这个例子中,所有可能的字符串都有3个或更少的E,2个或更少的O和3个或更少的U.

所以,就在我的脑海中,我想要回归

EEEOOUUU(源字符串) EEEOUUU EEEOOUU EEEOOU

EEOOUUU EEOUUU EEOOUUU EEOUU EEOU EOOUUU ......等等...

由于某些原因,递归拥有我这个,我甚至无法想象解决方案。 我有固定长度的字母排列的算法,但这在这里没有帮助,或者至少我的睡眠不足的大脑不能应用它们。

任何有些慷慨的帮助或建议可能愿意提供,我会感激你...

对于谈话的话题,这里的事情很糟糕,我只是被砍掉了,可能会被扔掉而不是代替什么......当然这假设了一些电话,我以后会因为只返回欺骗而被充实等对于数组的使用并不感到兴奋,但对于一堆入口术语来说,这不会重复。

//probably the most inefficent way of doign this, sorry for my level of fail.
-(NSMutableArray*) getDuplicatePermutations:(NSMutableArray*)workingArray workingWord:(NSMutableString*)workingWord currentLetter:(NSString*)currentLetter{
    NSArray *dupeArray = [self getDuplicateLetters];  //this returns only the letters with an occurrence >1 so in EEEIIOOOT, it returns "E", I", "O"
    if (workingWord==nil){workingWord = [[NSMutableString alloc] init];
        for (NSString *thisLetter in dupeArray)
        {
            for (NSString* thisLetterStuff in [self possibleDupePermutationsForLetter:thisLetter theWord:self]){  ////this thing returns NSArray of NSStrings like so "EEE","EE", "E"
                workingWord = [workingWord stringByAppendingString:thisLetterStuff];
                if ([thisLetter isEqualToString:[dupeArray lastObject]]) { ///do... something.. at the lowest depth...
                    [workingArray addObject:workingWord];
                    workingWord = @"";
                }
                workingArray = [self getDuplicatePermutations:workingArray workingWord:workingWord currentLetter:thisLetter];  //I can haz recursion?  No idea where to do it,actually.
            }
        }

    }
    return workingArray;    ///ostensibly an array filled with crap the looping mess builds
}

2 个答案:

答案 0 :(得分:1)

好吧,我发现了一种有效的方式......我觉得也许有人会敲我的门并带走我的驾驶执照和电脑......但是这里就是..

解决方案是这样的。

来自源词的每个字母都是重复的 构建一个“Dupe Map”,它本质上是一个带有字母键和出现次数值的字典“

用这个字母对单词部分播种(字母*它的出现次数 - 迭代次数)

对于字典中的每个其他字母,迭代,从这些字母的可能迭代中删除一个构建字部分的出现次数。

在外循环的每次迭代之后,重新创建重叠图并再次执行...

(显然,这包含了在实例上执行实用任务的其他一些方法) 但我至少想分享,即使它现在很糟糕,也可能是漏洞。

-(NSMutableArray*) DoCrazyCalculationsForDuplicatePermutations
{
    NSMutableArray *resArray = [[NSMutableArray alloc] init];
    NSArray *myDupes = [self getDuplicateLetters];
    for (NSString *thisLetter in myDupes){
        NSMutableDictionary *myDupeMap = [self getDupeMap];
        NSArray *keys = [myDupeMap allKeys];
        NSMutableString *wordSeed = [[NSMutableString alloc] init];
        NSNumber *seedNumberFromDictionary = [myDupeMap objectForKey:thisLetter];
        unsigned seedLettersToMake = [seedNumberFromDictionary intValue];
        [myDupeMap setValue:[NSNumber numberWithInt:1] forKey:thisLetter];  //1 Out the entry for this primary letter because we will handle it as part of the outer loop  -- also prevents 1 infinite loop below
        unsigned w = 0;
        for (w=1; w <= seedLettersToMake; w++) {
            myDupeMap = [self getDupeMap];  //reset the dupe map...
            [wordSeed appendString:[self getLettersByLetterAndCount:thisLetter count:1]];  //I will be appended inside the loop, per word;
            unsigned dupeTotals = [myDupeMap myTotals];
            while (dupeTotals >= ([myDupeMap count])) {
                NSMutableString *thisWord = [[NSMutableString alloc] init];
                [thisWord appendString:wordSeed];
                for (NSString *thisKey in keys){
                    if(![thisKey isEqualToString:thisLetter]){
                        NSNumber *numberFromDictionary = [myDupeMap objectForKey:thisKey];
                        unsigned lettersToMake = [numberFromDictionary intValue];//how many for this letter? 
                        [thisWord appendString:[self getLettersByLetterAndCount:thisKey count:lettersToMake]];
                        if (lettersToMake > 1){
                            unsigned o = lettersToMake - 1;
                            [myDupeMap setValue:[NSNumber numberWithInt:o] forKey:thisKey];
                            dupeTotals = [myDupeMap myTotals];
                        }
                    }
                }
                if (([thisWord length]-(w-1)) == ([myDupeMap count])) {dupeTotals=.5;} //break out
                NSLog(@"CrazyDuplicateProcessing: %@",[thisWord alphabetized]);
                [resArray addObject:thisWord];
            }
        }
    }
    return resArray;
}

答案 1 :(得分:0)

如果我理解你的要求,可以使用嵌套循环来完成。在伪代码中:

for e-count in 1 to 3:
    for o-count in 1 to 2
        for u-count in 1 to 3:
            create string with e-count e's, o-count o's and u-count u's