DAG优化
Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
大家都学过了代码优化,其中有一个DAG优化,这次我们就练习这个操作。
Input
输入第一行为一个整数n(n < 100),表示该组输入的表达式的个数
之后n行为表达式,每个变量为一个字母,表达式仅包括二元运算 + - * /
例如:A=B+C
Output
通过构造DAG图,进行代码优化,只需要保留AB,删除无用变量,删除变量时,尽量保留最早出现的变量。
PS:保证AB的值不同
Sample Input
3 A=B+C B=B+B A=C+C
Sample Output
B=B+B A=C+C
Hint
Source
#include<bits/stdc++.h>
using namespace std;
//答案没有A=D这种表达式
struct Node
{
int left ;
int right ;
char key;
vector<char> addition;
}node[110];
int num;//记录DAG图元素个数
vector<char>::iterator it;//用于遍历附加结点
bool Judge(char ch , int i)
{//判断结点是否存在于附加标记上
for(it = node[i].addition.begin() ; it!=node[i].addition.end(); it++)
if(*it == ch) return true;
return false;
}
int ADDKEY(char ch)
{
for(int i = num-1 ; i>=0 ; i--){
//如果变量存在于结点标记或者是附加标记,返回下标
if(node[i].key==ch || Judge(ch , i ))
return i ;
}
//否则添加新的结点
node[num].key = ch;
return num++;
}
void ADD(char ch , char op , int le , int ri)
{//添加附加标记
for(int i = num-1 ;i>=0 ; i--){
if(node[i].key == op && node[i].left == le && node[i].right == ri)
{
node[i].addition.push_back(ch);
return ;
}
}
node[num].addition.push_back(ch);
node[num].left = le;
node[num].right = ri;
node[num].key = op;
num++;
}
char ans[110][110];//保存---字符串表达式
int f[110];//标记
void dfs(int i){
if(node[i].left!=-1){
f[i] = 1;
dfs(node[i].left);
dfs(node[i].right);
}
}
int main()
{
int n , i ;
int le, ri;
scanf("%d",&n);
for(i = 0;i<110;i++){
node[i].left = -1;
node[i].right = -1;
}
num = 0;
getchar();
char str[110];
for(i = 0;i<n;i++)
{
scanf("%s",str);
le = ADDKEY(str[2]);
ri = ADDKEY(str[4]);
ADD(str[0], str[3], le , ri);
}
for(i = 0 ;i<num ; i++){
if(node[i].left != -1){
ans[i][0] = node[i].addition[0];
ans[i][1] = '=';
Node l = node[node[i].left];
Node r = node[node[i].right];
ans[i][2] = l.addition.size() > 0 ? l.addition[0] : l.key;
ans[i][3] = node[i].key;
ans[i][4] = r.addition.size() > 0 ? r.addition[0] : r.key;
ans[i][5] = 0;
}
}
for(i = num-1 ; i>=0 ; i--){
//从后向前搜索,标记最新的变量值
if(ans[i][0] == 'A'){
dfs(i);
break;
}
}
for(i = num-1; i>=0 ; i--){
if(ans[i][0] == 'B'){
dfs(i);
break;
}
}
for(i = 0 ; i<num ; i++){
if(f[i])
puts(ans[i]);
}
return 0;
}