N:DAG优化

DAG优化

Time Limit: 1000 ms Memory Limit: 65536 KiB

Submit Statistic

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;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值