C++ 查找给定字符串的所有交错,这些交错可以由保留字符顺序的第一个和第二个字符串的所有字符组成

C++ 查找给定字符串的所有交错,这些交错可以由保留字符顺序的第一个和第二个字符串的所有字符组成,c++,recursion,C++,Recursion,我试图找到给定字符串的所有交错,这些交错可以由第一个和第二个字符串的所有字符组成,其中保留了字符顺序 我尝试使用递归 // This code works[Snippet 1] void func(string str1,string str2,string temp){ if(!str1.length() && !str2.length()){ cout << temp << endl; return;

我试图找到给定字符串的所有交错,这些交错可以由第一个和第二个字符串的所有字符组成,其中保留了字符顺序

我尝试使用递归

// This code works[Snippet 1]
void func(string str1,string str2,string temp){

    if(!str1.length() && !str2.length()){
        cout << temp << endl;
        return;
    }

    if(str1.length()){
        func(str1.substr(1),str2,temp+str1[0]);
    }

    if(str2.length()){
        func(str1,str2.substr(1),temp+str2[0]);
    }
}

// This code does not work[Snippet 2]
void func(string str1,string str2,string temp){

    if(!str1.length() && !str2.length()){
        cout << temp << endl;
        return;
    }

    if(str1.length()){
        temp+=str1[0];
        func(str1.substr(1),str2,temp);
    }

    if(str2.length()){
        temp+=str2[0];
        func(str1,str2.substr(1),temp);
    }
}
//此代码有效[Snippet 1]
void func(字符串str1、字符串str2、字符串temp){
如果(!str1.length()&&!str2.length()){

cout我认为您应该使用std::next_permutation()。对于第一个字符串,为每个字符添加一个0到一个向量。对于第二个字符串,为1添加一个0。现在您有一个向量要置换。对于每个置换,只要将索引重新映射回第一个字符串中的下一个字符(如果它是偶数)和第二个字符(如果是奇数)


置换示例:“cat”、“bird”到(0 0 0 1 1 1 1 1),一个置换变成(0 1 1 0 1 1 1 1 1),您可以将其重新映射到“cbiartd”

这里有一个版本,有大量的
cout
和跟踪递归深度的方法

#include <iostream>
#include <string>

using namespace std;

void func0(string str1, string str2, string temp, int depth) {

    if (!str1.length() && !str2.length()) {
        cout << temp << endl;
        depth--;
        return;
    }

    if (str1.length()) {
        cout << "depth: " << depth++ << "|temp: " << temp << '\n';
        func0(str1.substr(1), str2, temp + str1[0], depth);
    }

    if (str2.length()) {
        cout << "depth: " << depth++ << "|temp: " << temp << '\n';
        func0(str1, str2.substr(1), temp + str2[0], depth);
    }

    depth--;
}

void func1(string str1, string str2, string temp, int depth) {
    if (!str1.length() && !str2.length()) {
        cout << temp << endl;
        depth--;
        return;
    }

    if (str1.length()) {
        temp += str1[0]; //temp has
        cout << "depth: " << depth++ << "|temp: " << temp << '\n';
        func1(str1.substr(1), str2, temp, depth);
    }

    if (str2.length()) {
        temp += str2[0];
        cout << "depth: " << depth++ << "|temp: " << temp << '\n';
        func1(str1, str2.substr(1), temp, depth);
    }

    depth--;
}

int main(int argc, char* argv[]) {
    string a = "asd";
    string b = "qw";
    string c = "";

    cout << "func0\n";
    func0(a, b, c, 0);
    cout << "func1\n";
    func1(a, b, c, 0);

    return 0;
}
对于func1:

func1
depth: 0|temp: a
depth: 1|temp: as
depth: 2|temp: asd
depth: 3|temp: asdq
depth: 4|temp: asdqw
asdqw
depth: 3|temp: asdq
depth: 4|temp: asdqd
depth: 5|temp: asdqdw
asdqdw
depth: 5|temp: asdqdw
depth: 6|temp: asdqdwd
asdqdwd
depth: 2|temp: asq
depth: 3|temp: asqs
depth: 4|temp: asqsd
depth: 5|temp: asqsdw
asqsdw
depth: 5|temp: asqsdw
depth: 6|temp: asqsdwd
asqsdwd
depth: 4|temp: asqsw
depth: 5|temp: asqsws
depth: 6|temp: asqswsd
asqswsd
depth: 1|temp: aq
depth: 2|temp: aqa
depth: 3|temp: aqas
depth: 4|temp: aqasd
depth: 5|temp: aqasdw
aqasdw
depth: 5|temp: aqasdw
depth: 6|temp: aqasdwd
aqasdwd
depth: 4|temp: aqasw
depth: 5|temp: aqasws
depth: 6|temp: aqaswsd
aqaswsd
depth: 3|temp: aqaw
depth: 4|temp: aqawa
depth: 5|temp: aqawas
depth: 6|temp: aqawasd
aqawasd
若要帮助查看递归,请在深度为1时查看正确的输出,将其作为具有2个分支的树的第一级。它们应该只是每个字符串的第一个字符。现在,这些节点中的每个节点都为每个剩余字符获取子级。在下一个较低级别(深度2),您添加一个字符,然后这些节点中的每一个都让子节点创建级别/深度3…等等。正确完成后,它将构建一个trie,并且
temp
在每个深度仅更改一次长度

在这两种情况下,当你到达一片叶子时,你可以从底部开始打印


在不正确的版本中,您将看到
temp
的长度在给定的递归深度中不一致。如前所述,但以不同的方式,附加到
temp
并将其存储在本地(这也可以被认为是在trie的行/级别/深度中追加)导致
temp
的长度从左到右和从上到下增长。

有问题吗?否则请使用工作代码;-)我想知道代码段2中的错误。@pawan正如您所说,在将临时字符串传递到函数之前,我已将该字符追加到临时字符串中。问题是,在进行se时,第一个追加仍然存在cond recursive call。这种方法还应适用于3个字符串(加2)或更多。只需确保从最低到最高排序的数字开始,因为std::next_permutation的文档要求起始值按字典顺序为最低排列(否则将跳过一整组)
func1
depth: 0|temp: a
depth: 1|temp: as
depth: 2|temp: asd
depth: 3|temp: asdq
depth: 4|temp: asdqw
asdqw
depth: 3|temp: asdq
depth: 4|temp: asdqd
depth: 5|temp: asdqdw
asdqdw
depth: 5|temp: asdqdw
depth: 6|temp: asdqdwd
asdqdwd
depth: 2|temp: asq
depth: 3|temp: asqs
depth: 4|temp: asqsd
depth: 5|temp: asqsdw
asqsdw
depth: 5|temp: asqsdw
depth: 6|temp: asqsdwd
asqsdwd
depth: 4|temp: asqsw
depth: 5|temp: asqsws
depth: 6|temp: asqswsd
asqswsd
depth: 1|temp: aq
depth: 2|temp: aqa
depth: 3|temp: aqas
depth: 4|temp: aqasd
depth: 5|temp: aqasdw
aqasdw
depth: 5|temp: aqasdw
depth: 6|temp: aqasdwd
aqasdwd
depth: 4|temp: aqasw
depth: 5|temp: aqasws
depth: 6|temp: aqaswsd
aqaswsd
depth: 3|temp: aqaw
depth: 4|temp: aqawa
depth: 5|temp: aqawas
depth: 6|temp: aqawasd
aqawasd