【问题标题】:check if one string is interleaved by two other strings检查一个字符串是否被另外两个字符串交错
【发布时间】:2015-10-25 05:38:11
【问题描述】:

我正在调试以下问题。发布详细的问题陈述和编码。我的问题是最后一个 else if (else if (A[i-1]==C[i+j-1] && B[j-1]==C[i+j-1])) 是否是必要的?我认为没有必要,因为它总是被 else if(A[i-1]==C[i+j-1] && B[j-1]!=C[i+j-1]) 覆盖,或者被 else if (A[i-1]!=C[i+j-1] && B[j-1]==C[i+j-1]) 覆盖,即前两个 if-else 检查条件。谢谢。

给定s1、s2、s3,判断s3是否由s1和s2交织而成。

例如, 鉴于: s1 = "aabcc", s2 = "dbbca",

当 s3 = "aadbbcbcac" 时,返回 true。 当 s3 = "aadbbbaccc" 时,返回 false。

// The main function that returns true if C is
// an interleaving of A and B, otherwise false.
bool isInterleaved(char* A, char* B, char* C)
{
    // Find lengths of the two strings
    int M = strlen(A), N = strlen(B);

    // Let us create a 2D table to store solutions of
    // subproblems.  C[i][j] will be true if C[0..i+j-1]
    // is an interleaving of A[0..i-1] and B[0..j-1].
    bool IL[M+1][N+1];

    memset(IL, 0, sizeof(IL)); // Initialize all values as false.

    // C can be an interleaving of A and B only of sum
    // of lengths of A & B is equal to length of C.
    if ((M+N) != strlen(C))
       return false;

    // Process all characters of A and B
    for (int i=0; i<=M; ++i)
    {
        for (int j=0; j<=N; ++j)
        {
            // two empty strings have an empty string
            // as interleaving
            if (i==0 && j==0)
                IL[i][j] = true;

            // A is empty
            else if (i==0 && B[j-1]==C[j-1])
                IL[i][j] = IL[i][j-1];

            // B is empty
            else if (j==0 && A[i-1]==C[i-1])
                IL[i][j] = IL[i-1][j];

            // Current character of C matches with current character of A,
            // but doesn't match with current character of B
            else if(A[i-1]==C[i+j-1] && B[j-1]!=C[i+j-1])
                IL[i][j] = IL[i-1][j];

            // Current character of C matches with current character of B,
            // but doesn't match with current character of A
            else if (A[i-1]!=C[i+j-1] && B[j-1]==C[i+j-1])
                IL[i][j] = IL[i][j-1];

            // Current character of C matches with that of both A and B
            else if (A[i-1]==C[i+j-1] && B[j-1]==C[i+j-1])
                IL[i][j]=(IL[i-1][j] || IL[i][j-1]) ;
        }
    }

    return IL[M][N];
}

提前致谢, 林

【问题讨论】:

  • 我认为您确实需要最后一个案例。例如,A="aaaa"、B="aaaa" 和 C="aaaaaaaa" 时会发生什么。
  • 另外,您的算法还有其他问题。例如,我看不到您将IL[][] 的任何元素设置为false 的任何地方。您的函数可能总是返回true。您可能需要一个最终的 else 块,其中应将 IL[i][j] 设置为 false。
  • 在最后一个 else if 块中放置一个断点或打印,看看程序是否在我上面提到的示例中到达那里。正如代码中的 cmets 所说,前两个 else if 语句不会捕获 C 中的字符与 A 和 B 中的字符匹配的条件。
  • 我认为它更干净。但是,我确实建议将 char* 的使用替换为 std::string。如果你想继续使用char*,至少声明参数const char*,因为你没有修改它们。这样您就可以使用字符串文字和const 字符串调用该函数。例如,isInterleaved("aaa", b, c).
  • 完成。但不要犹豫answer your own questions。没关系,值得鼓励。 :D

标签: c++ algorithm


【解决方案1】:

您确实需要最终的else if 来捕捉C 中的下一个字符与A 和B 中的下一个字符匹配的情况。例如,使用A="aaaa"、B="aaaa" 和C="aaaaaaaa" 运行您的程序看看你是否输入了最后一个else if 块。

此外,您还需要一个最终的else 块来处理前面的条件都不匹配的情况。在这种情况下,您需要将IL[i][j] 设置为false。否则,该函数将错误地返回true。

编辑:即使代码使用memset 将IL 的所有元素初始化为0,它也可能不起作用,因为ISO C++ does not support 可变长度数组(VLA)。其实这就是我tried the code at cpp.sh时发生的事情。它使用带有标志的 g++-4.9.2 导致它报告 sizeof(IL) 为 1,即使 g++ 应该支持 VLA。也许这是一个编译器错误,或者它不支持多维 VLA。无论如何,根本不使用它们可能更安全。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-11
    • 2013-12-09
    • 2013-03-13
    • 1970-01-01
    • 2013-05-12
    • 2011-02-07
    • 1970-01-01
    相关资源
    最近更新 更多