给出一些不合法的括号表达式,然你求出最短的合法的
s[]是读入的字符串
f[i][j]是i到j的最少的添加数
c[i][j]是对应的添加方案
分几种情况
s[i] == '[' 在右端添 ']' 并求解 s[i + 1][j]
s[i] == '('
s[j] == ')'
s[j] == ']'类似处理
s[i] == '[' && s[j] == ']' ,求解s[i + 1][j - 1]
s[i] == '(' && s[j] == ')', 类似
除了这些特殊情况外。
对 i <= k < j
分别求解s[i][k] 和 s[k + 1][j]
#include<iostream> #include<string> #include<cstring> #include <cstdio> using namespace std; string s; int d[101][101], value[101][101], length; void fun() { for (int p = 0; p < length; p++)d[p][p] = 1; for (int tem = 1; tem < length; tem++) for (int i = 0; i < length - tem; i++) { int j = tem + i; d[i][j] = 99999; if ((s[i] == '(' && s[j] == ')') || (s[i] == '[' && s[j] == ']'))//1@ { d[i][j] = d[i + 1][j - 1]; value[i][j] = -1; } for (int k = i; k < j; k++)//此处需要注意,即便1@处成立,也不能省略 if (d[i][j] > d[i][k] + d[k + 1][j]) { d[i][j] = d[i][k] + d[k + 1][j]; value[i][j] = k; } } return; } void print(int i, int j) { if (i > j)return; else if (i == j) { if (s[i] == '(' || s[i] == ')') printf("()"); if (s[i] == '[' || s[i] == ']')printf("[]"); }else if (value[i][j] == -1) { printf("%c", s[i]); print(i + 1, j - 1); printf("%c", s[j]); }else { print(i, value[i][j]); print(value[i][j] + 1, j); } return; } int main() { while (getline(cin, s)) { memset(d, 0, sizeof(d)); length = (int)s.length(); fun(); print(0, length - 1); printf("\n"); } return 0; }