我的字符串连接的递归解决方案是正确的吗?

时间:2015-10-05 00:33:02

标签: algorithm recursion dynamic-programming

问题:给定三个字符串A,B和C.编写一个函数,检查C是否是A和B的交织。如果C包含A和B的所有字符并且顺序,则称其为交错A和B.保留单个字符串中的所有字符。 例: A =" AB",B =" CD",C = CDAB 在这种情况下,C是A和B的串联字符串。

我在C中写了下面的代码。想知道我是否遗漏了任何测试用例或者是否可以改进。 逻辑只是用A和B检查C的每个字符,并使用递归来增加索引。

#include <stdio.h>

int is_concatenated(char *g1, char *g2, int m, int n, int l, char *target, int i, int j, int k)
{
    if (m+n > l)
        return 0;
    if (k == l)
        return 1;
    /* for handling duplicated characters in A and B */
    if ((i < m ) && g1[i] == target[k] && (j < n) && g2[j] == target[k]) {
        return is_concatenated(g1, g2, m, n, l, target, i+1, j, k+1) || is_concatenated(g1, g2, m, n, l, target, i, j+1, k+1);
    }

    if ((i < m ) && g1[i] == target[k]) {
        return is_concatenated(g1, g2, m, n, l, target, i+1, j, k+1);
    }
    if ((j < n) && g2[j] == target[k]) {
        return is_concatenated(g1, g2, m, n, l, target, i, j+1, k+1);
    }
    return 0;
}

int main(void) {
    char *g1 = "ABCD";
    char *g2 = "BCDX";
    char target[] = {"ABBCDXBCD"};
    printf("%d\n", is_concatenated(g1, g2, strlen(g1), strlen(g2), strlen(target), target, 0, 0, 0));
    return 0;
}

3 个答案:

答案 0 :(得分:3)

您的解决方案是正确的,但问题是您的最坏情况复杂度为2^{min(m, n)}。考虑以下情况:

g1 = 1111111111111111111111111111112
g2 = 1111111111111111111111111111113
target = 11111111111111111111111111111131111111111111111111111111111112

然后,您可能对更有效的解决方案感兴趣。有一个使用动态编程的O(nm)解决方案。我的想法是使用f[i][j]数组f[i][j] = 1 target[0...i+j-1]当且仅当g1[0...i-1]g2[0...j-1]-1的交错时。 Reference

答案 1 :(得分:0)

到目前为止,代码看起来是正确的。 Here是对这个问题的一个很好的讨论。我喜欢提到std :: next_permutation()。也许您可以使用std库函数来测试代码。

答案 2 :(得分:0)

根据问题陈述,我想你的代码应该为给定的输入打印1。如果我错了,请纠正我。

如果输出应该为0,那么你的逻辑和代码就完全可以了。

但是如果输出应该是1,我担心你的代码会返回给定输入的错误输出。这是因为对于给定的案例,您的变量 k 永远不会达到目标长度 l

g1 中的字符 时,您可以通过增加 k 来使其有效g2 目标 字符串中的 k 字符不匹配。并且还要检查边界条件中字符串 g1 g2 的长度。

希望这能让您的代码输出正确。