在 C++ 中打印两个字符串的所有交叉组合

2024 年 8 月 28 日 | 3 分钟阅读

在本文中,我们将讨论如何在 C++ 中打印给定两个字符串的所有交错。但在深入实现之前,我们将先了解交错。

什么是交错?

两个字符串的交错是通过以所有可能的方式合并两个字符串的字符,同时保持其相对顺序而形成的。例如,“AB”和“CD”的交错是“ABCD”、“ACBD”、“ACDB”、“CABD”、“CADB”和“CDAB”。

打印给定两个字符串所有可能交错的问题是一个常见的递归和动态规划问题。

问题陈述

给定两个字符串str1str2,打印这两个字符串的所有可能交错。交错字符串保留单个字符串中字符的顺序。

例如

str1 = "AB"

str2 = "CD"

可能的交错

ABCD

ACBD

ACDB

CABD

CADB

CDAB

1. 朴素递归方法

一个简单的递归解决方案是在每一步从任一字符串中选择一个字符来生成所有交错。

  • 如果str1非空,则递归地为str1[1...]str2生成交错。将str1[0]添加到结果的前面。
  • 如果str2非空,则递归地为str1str2[1...]生成交错。将str2[0]添加到结果的前面。

基本情况

  • 如果两个字符串都为空,则打印生成的交错。
  • 如果其中一个字符串为空,则只从非空字符串中选择字符。

它的时间复杂度是指数级的O(2^n),其中 n 是两个字符串的长度。

示例

让我们举一个例子来打印 C++ 中给定两个字符串的所有交错

输出

ABCD
ACBD
ACDB
CABD
CADB
CDAB

这会以字典序递归地生成所有有效的交错。

2. 动态规划方法

我们可以使用自底向上的动态规划方法对其进行优化。

  • 创建一个二维矩阵 dp[m+1][n+1] 来存储交错。
  • 从空字符串到完整字符串,对角线填充矩阵。
  • 填充单元格 dp[i][j]
    1. 将 str1[i-1] 附加到 dp[i-1][j] 的交错中
    2. 将 str2[j-1] 附加到 dp[i][j-1] 的交错中
  • 最终的交错将存储在 dp[m][n] 中。
  • 它将复杂度降低到O(m*n),因为我们存储结果而不是重新计算。

示例

实现动态规划方法的 C++ 代码

输出

ABCD
ACBD
ACDB 
CABD
CADB
CDAB

这种自底向上的 DP 方法避免了重复计算,并提高了递归方法的效率。