卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章17278本站已运行3326

计算需要移除的配对数,以使所有平衡括号子序列为空

计算需要移除的配对数,以使所有平衡括号子序列为空

C 编译器将字符串视为字符数组,因此很容易根据位置删除字符串中的字符。必须检查字符串的第一个和最后一个位置是否存在括号,并且必须将其删除。该字符串可以复制到另一个变量中并显示。

C 中有许多预定义函数可以有效地用来操作字符串。在 C 语言中,借助函数可以轻松实现从起始位置或结束位置删除字符。

从字符串中删除开始和结束括号

括号是单个字符,是输入字符串的一部分,可以按照下面给出的逻辑和算法从字符串中删除

字符是我们在键盘上看到的任何字母数字键,它存储在 C 中的字符变量中。

() 在 c 中被称为括号。我们需要在用户输入的字符串中识别该字符,并将其从字符串中删除。

数组是一个变量,它具有许多由单个名称和连续编号寻址的存储位置,而字符串是一个字符数组。

在很多情况下,我们需要从字符串中删除括号,例如在解决正则表达式时。

语法

函数 countRemoval 接受字符串 str 作为输入并返回一个整数值,该值表示使字符串中所有平衡括号子序列为空所需的删除对的数量。该函数使用变量 count 来跟踪所需的删除次数,最初设置为 0。它还使用变量 Balance 来跟踪字符串中左括号和右括号的数量之间的平衡。然后该函数迭代字符串的长度并检查每个索引处的字符。如果该字符是左括号,则余额加1,如果是右括号,则余额减1。如果余额变为负数,则说明多了一个右括号,移除次数为加 1,余额重置为 0。循环后,计数更新为包括剩余余额除以 2,作为使字符串中所有平衡括号子序列为空所需的删除量。

'
int countRemoval(string str) {
   int count = 0;
   int balance = 0;
   for (int i = 0; i < str.length(); i++) {
      if (str[i] == '(') {
         balance++;
      } else {
         balance--;
      }
      if (balance < 0) {
         count++;
         balance = 0;
      }
   }
   count += balance / 2;
   return count;
} 

算法

  • 第 1 步 - 声明 str1、str2,初始化为 null。

  • 第 2 步 - 声明整型变量 len,n,i

  • 第 3 步 - 从控制台接受 str1

  • 第 4 步 - 检查第一个字符是否为 (

  • 步骤 5 - 如果是 n = 1

  • 第 6 步 - 当 n

  • 第 7 步 - 检查 str2 的最后一个字符是否为 )。

  • 第 8 步 - 如果是,请将其替换为 0。

  • 第 9 步 - 打印 str2,其中包含输入字符串减号 ()。

方法

方法 1 - 暴力递归:在第一种方法中,我们使用暴力递归来查找所有可能的子序列并检查它们是否平衡。如果子序列是平衡的,我们删除一对括号并计算删除的括号对的数量。我们计算清空字符串所需的最少对删除次数。

方法 2 - 动态编程:第二种方法使用动态编程来优化解决方案。我们可以使用 2D DP 表来存储从索引“i”到“j”的子串所需的最小删除次数。我们迭代字符串并根据给定条件填充 DP 表。

方法 1 暴力递归

代码

在这段代码中,我们检查所有可能的子序列组合,这导致了指数时间复杂度。对于较大的输入,此方法可能效率不高。

'
#include <iostream>
#include <string>
using namespace std;

int countRemovalsRecursion(const string &s, int index, int open) {
   if (index == s.size()) {
      return open;
   }

   if (s[index] == '(') {
      return countRemovalsRecursion(s, index + 1, open + 1);
   } else if (open > 0) {
      return countRemovalsRecursion(s, index + 1, open - 1);
   } else {
      return 1 + countRemovalsRecursion(s, index + 1, open);
   }
}

int main() {
   string s = "(()())(";
   cout << "Input string: " << s << endl;
   cout << "Minimum removals (Brute Force Recursion): " << countRemovalsRecursion(s, 0, 0) << endl;
   return 0;
}

输出

'
Input string: (()())(
Minimum removals (Brute Force Recursion): 1

方法2

示例

此动态规划解决方案计算清空所有平衡括号子序列所需的最小删除次数。它迭代字符串,用左括号的数量更新一维 DP 表,并返回最终 DP 值作为最小移除量。

'
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int countRemovalsDP(const string &s) {
   int n = s.size();
   vector<int> dp(n + 1, 0);

   for (int i = 0; i < n; ++i) {
      if (s[i] == '(') {
         dp[i + 1] = dp[i] + 1;
      } else {
         dp[i + 1] = max(dp[i] - 1, 0);
      }
   }
   return dp[n];
}

int main() {
   string s = "(()())()";
   cout << "Input string: " << s << endl;
   cout << "Minimum removals (Dynamic Programming): " << countRemovalsDP(s) << endl;
   return 0;
}

输出

'
Input string: (()())()
Minimum removals (Dynamic Programming): 0

结论

C语言的基本概念,如字符和字符串数据类型有什么区别,字符串分隔符,如何初始化字符串和数组,数组第一个字符为索引0的位置的计算并且该程序中使用最后一个字符必须为空才能获得正确的输出。

程序中括号的删除是通过实现 C 编程的基本、简单概念来实现的。

卓越飞翔博客
上一篇: 递归程序在C++中插入一个星号在一对相同字符之间
下一篇: 返回列表

相关推荐

留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏