删括号--动态规划
采用数组模拟栈的入栈出栈 进行匹配 通过仅有 ~通过率97.3% 因为这类型的解不了 退栈进栈的方式 跟下面代码思路差不多
但是对于下面这种情况的处理无法解决 所以换种思路结合动态规划的思路 每一次查询都有自己作用 并把作用交给下一次查找
(()(()))
()()
删括号的时候一定要时刻保证左括号数量比右括号多或者等于(最后才等于),我们可以定义dp[i][j][k]表示考虑AA前ii个匹配了BB前jj个AA被删除部分左括号数-右括号数=k是否可行,分类讨论转移即可,最后答案就是dp[n][m][0]
(()......) => () 对于这种类型不知道删除外面还是只能分类讨论 按删外面试 这里代码的思路有点像“编辑路径”的算法
只是这里是括号匹配相对比较困难
下面的代码思路是输入字符串转化为目标字符串 这里是第一个字符开始试 第二个试..................
import java.util.*;
public class Main {
final static int NUM = 105;
static int dp[][][] = new int[NUM][NUM][NUM];
static char a[] = new char[NUM];
static char b[] = new char[NUM];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s1 = sc.nextLine();
String s2 = sc.nextLine();
int n = s1.length();
int m = s2.length();
for (int i = 1; i <= n; i++) {
a[i] = s1.charAt(i - 1);
}
for (int i = 1; i <= m; i++) {
b[i] = s2.charAt(i - 1);
}
dp[0][0][0] = 1;
for(int i = 0 ; i < n ; i++) {
for(int j = 0 ;j <= m ; j++) {
for(int k = 0 ; k <= i ; k++) {
if(dp[i][j][k]!=0) {//建立在前人的基础上 !=0 证明还有( 还没匹配完
if(k==0 && a[i+1]==b[j+1])
dp[i+1][j+1][k]=1;
if(a[i+1]=='(')
dp[i+1][j][k+1]=1;
else if(k!=0)
dp[i+1][j][k-1]=1; //能匹配到第一位是 1 为正确答案
}
}
}
}
if(dp[n][m][0]==1)
System.out.println("Possible");
else System.out.println("Impossible");
}
}
#include "pch.h"
#include<iostream>
const int N = 105;
int n, m, i, j, k;
char a[N], b[N];
bool f[N][N][N];
int main()
{
scanf("%s%s", a + 1, b + 1);
n = strlen(a + 1), m = strlen(b + 1);
f[0][0][0] = 1;
for (i = 0; i < n; ++i)
for (j = 0; j <= m; ++j)
for (k = 0; k <= n; ++k)
if (f[i][j][k])
//如果前面状态有可能转化成目标状态,0进行下一操作
{
if (!k && a[i + 1] == b[j + 1])
//当删除正好为(),且符合目标状态
f[i + 1][j + 1][k] = 1;
if (a[i + 1] == '(')
//或者为可删除的状态,先判断(,保证左括号的数量大于右括号
//删去(,差值k加一
f[i + 1][j][k + 1] = 1;
else if (k)
//凑够(),删去)差值k减一 也就是a有一部分可以满足条件 继续判断
f[i + 1][j][k - 1] = 1;
}
//输出()差值k为0的值
puts(f[n][m][0] ? "Possible" : "Impossible");
}
if else 的疑问
if(a)
b;
if(c)
d;两个if都会进入判断。
if(a)
b;
else if(c)
d;//当满足a的时候就不进入到c的判断,不满足a时,才会去判断c