void-man

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

给出一些不合法的括号表达式,然你求出最短的合法的

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;
}
posted on 2011-05-31 22:58  void-man  阅读(190)  评论(0)    收藏  举报