递归 - 子集 - C ++

时间:2012-09-07 00:11:20

标签: c++ recursion

谢谢@Scotty,@ paddy。仅供参考,最佳解决方案是:

void RecSubsets(string soFar, string rest) {
    if (rest == "") {
        cout << soFar << end;
    }
    else {
      RecSubsets(soFar + rest[0], rest.substr(1));
      RecSubsets(soFar, rest.substr(1));
    }
 }

void CanMakeSum(string set) {
    RecSubsets("", set);
 }

我正在编写一个简单的程序,通过将数据分成2组(C(n-1,k-1)&amp; C(n-1,k))来计算集合中所有可能的组合并调用函数递归。 以下是我写的:

void RecSubsets(string soFar, string rest) {
    if (rest == "") cout << soFar << end;
    }
    else {
        for (int i = 0; i < rest.length(); i++) {
            string next = soFar + rest[i];
            string remaining = rest.substr(i+1);
            RecSubsets(next, remaining);
        }
    }
}

void CanMakeSum(string set) {
    RecSubsets("", set);
    RecSubsets("", set.substr(1));
}

int main() {    
    string set = "abcd";
    CanMakeSum(set);
    return 0;
}

因此,对于'abcd'的输入字符串,它将分为2组(abcd和abc),然后通过递归调用函数打印出组合。根据这个逻辑,输出应该是:abcd,abc,abd,ab,acd,ac,ad,a ...... 但是,使用上面的程序,输出是abcd,abd,acd,ad ... 我从概念上理解我正在努力实现的目标,但我很难将其转换为代码。有人可以指出我出错的地方吗?感谢

2 个答案:

答案 0 :(得分:0)

这是一次很好的尝试。只有两个小问题:

  1. 你应该“将数据分成两组(C(n-1,k-1)&amp; C(n-1,k))”。这就是你的递归函数的用途!

  2. RecSubsets()始终打印出soFar。删除if (rest == "")

  3. 例如:

    void RecSubsets(string soFar, string rest) {
        // First print out "a" or wherever we are up to
        // This ensures we correctly get "ab" and "ac" without trailing characters etc
        cout << soFar << end;
    
        // Now print out the other combinations that begin with soFar
        // This part of your algorithm was already correct :)
        for (int i = 0; i < rest.length(); i++) {
            string next = soFar + rest[i];
            string remaining = rest.substr(i+1);
            RecSubsets(next, remaining);
        }
    }
    
    void CanMakeSum(string set)
    {
        RecSubsets("", set);
        // Don't call it a second time here
    }
    

答案 1 :(得分:0)

您希望按顺序打印结果而不是预订。另一个答案几乎是正确的,但你很容易就把它解雇了。它没有进行排列,因为没有重新排序字符串。

按照您需要的顺序输出数据的正确代码是:

void RecSubsets(string soFar, string rest) {
    for (int i = 0; i < rest.length(); i++) {
        string next = soFar + rest[i];
        string remaining = rest.substr(i+1);
        RecSubsets(next, remaining);
    }
    if( soFar.size() > 0 ) cout << soFar << endl;
}

输出:

abcd
abc
abd
ab
acd
ac
ad
a
bcd
bc
bd
b
cd
c
d
bcd
bc
bd
b
cd
c
d