簡體   English   中英

查找可以由保留字符串順序的第一和第二個字符串的所有字符組成的給定字符串的所有交織

[英]Find all interleavings of given strings that can be formed from all the characters of first and second string where order of characters is preserved

我試圖找到可以由保留字符串順序的第一和第二字符串的所有字符組成的給定字符串的所有交織

我試圖使用遞歸。

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

片段1和片段2之間的區別在於,在片段2中,我在將temp字符串附加到該字符之前,將其傳遞給函數。 第二個代碼給出result(string),其大小大於兩個輸入字符串的長度之和。

下面是用大量的版本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;
}

這將為func0產生以下輸出:

func0
depth: 0|temp:
depth: 1|temp: a
depth: 2|temp: as
depth: 3|temp: asd
depth: 4|temp: asdq
asdqw
depth: 3|temp: as
depth: 4|temp: asq
depth: 5|temp: asqd
asqdw
depth: 5|temp: asq
depth: 6|temp: asqw
asqwd
depth: 2|temp: a
depth: 3|temp: aq
depth: 4|temp: aqs
depth: 5|temp: aqsd
aqsdw
depth: 5|temp: aqs
depth: 6|temp: aqsw
aqswd
depth: 4|temp: aq
depth: 5|temp: aqw
depth: 6|temp: aqws
aqwsd
depth: 1|temp:
depth: 2|temp: q
depth: 3|temp: qa
depth: 4|temp: qas
depth: 5|temp: qasd
qasdw
depth: 5|temp: qas
depth: 6|temp: qasw
qaswd
depth: 4|temp: qa
depth: 5|temp: qaw
depth: 6|temp: qaws
qawsd
depth: 3|temp: q
depth: 4|temp: qw
depth: 5|temp: qwa
depth: 6|temp: qwas
qwasd

而對於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 ...等。 正確完成后,它會建立一個特例,並且temp在每個深度僅更改一次長度。

在這兩種方法中,您都將觸底並在到達葉子時進行打印。

在不正確的版本中,您將看到在給定的遞歸深度中temp長度不一致。 如前所述,但以不同的方式,將temp附加並存儲在本地(也可以將其視為仍在特里的行/級別/深度中附加)會導致temp長度從左到右和從頂部增加到底部。

我認為您應該使用std :: next_permutation()。 對於第一個字符串,為每個字符向向量添加0。 使用1對第二個字符串執行相同的操作。現在,您可以對一個向量進行排列。 對於每個排列,只需將索引重新映射回第一個字符串中的下一個字符(如果它為偶數),第二個就為奇數。

排列示例:“ cat”,“ bird”到(0 0 0 1 1 1 1 1),一個排列變成(0 1 1 0 1 0 1),您可以將其重新映射到“ cbiartd”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM