【数算A】表达式·表达式树·表达式求值

这道题在输出上太坑了,画出来不像树...

  1 #include<iostream>
  2 #include<cstring>
  3 #include<stack>
  4 using namespace std;
  5 int val[26],n,len,ans,maxDep;
  6 char infix[55],postfix[55],out[50][300];
  7 struct node{
  8     int ch;
  9     node *l,*r;
 10     node(){
 11         l=r=NULL;
 12     }
 13 }*root;
 14 //计算a^b
 15 int pow(int a,int b){
 16     int res=1;
 17     for(int i=1;i<=b;i++)
 18         res*=a;
 19     return res;
 20 }
 21 //将中缀转化为后缀表达式
 22 void infixToPost(char *s){
 23     len=strlen(s);
 24     int i=0;
 25     stack<char> S;
 26     for(int j=0;j<len;j++){
 27         if(isalpha(s[j])) postfix[i++]=s[j];
 28         else if(s[j]==‘(‘) S.push(s[j]);
 29         else if(s[j]==‘)‘){
 30             while(!S.empty()&&S.top()!=‘(‘){
 31                 postfix[i++]=S.top();
 32                 S.pop();
 33             }
 34             if(!S.empty()) S.pop();
 35         }
 36         else{
 37             while(!S.empty()&&S.top()!=‘(‘&&(s[j]==‘+‘||s[j]==‘-‘||S.top()==‘*‘||S.top()==‘/‘)){
 38                 postfix[i++]=S.top();
 39                 S.pop();
 40             }
 41             S.push(s[j]);
 42         }
 43     }
 44     while(!S.empty()){
 45         postfix[i++]=S.top();
 46         S.pop();
 47     }
 48     postfix[i]=0;
 49     len=i;          //把len设置为postfix的长度
 50 }
 51 //根据建的树求值
 52 int cal(node *cur){
 53     if(isalpha(cur->ch)) return val[cur->ch-‘a‘];
 54     else{
 55         switch(cur->ch){
 56             case ‘+‘:return cal(cur->l)+cal(cur->r);
 57             case ‘-‘:return cal(cur->l)-cal(cur->r);
 58             case ‘*‘:return cal(cur->l)*cal(cur->r);
 59             case ‘/‘:return cal(cur->l)/cal(cur->r);
 60         }
 61     }
 62 }
 63 //找到树的高度
 64 int findDep(node *cur){
 65     if(!cur) return 0;
 66     int l=findDep(cur->l);
 67     int r=findDep(cur->r);
 68     return l>r?l+1:r+1;
 69 }
 70 //将要打印的内容输出到out中
 71 void print(node *cur,int x,int y,int space){
 72      out[x][y]=cur->ch;
 73      if(cur->l){
 74          out[x+1][y-1]=‘/‘;
 75          print(cur->l,x+2,y-space,space>>1);
 76      }
 77      if(cur->r){
 78          out[x+1][y+1]=‘\\‘;
 79          print(cur->r,x+2,y+space,space>>1);
 80      }
 81 }
 82 //打印树
 83 void printTree(){
 84     //我们已经知道m层的树有2m-1层输出,所以直接利用这一点即可(out[]的输出范围为0~2m-2)
 85     for(int i=0;i<2*maxDep-1;i++){
 86         int j=299;
 87         while(out[i][j]==‘ ‘) j--;
 88         out[i][j+1]=0;
 89         cout<<out[i]<<endl;
 90     }
 91 }
 92 //建树
 93 void build(){
 94     stack<node*> S;
 95     for(int i=0;i<len;i++){
 96         node *t=new node;
 97         t->ch=postfix[i];
 98         if(!isalpha(t->ch)){
 99             t->r=S.top();S.pop();
100             t->l=S.top();S.pop();
101         }
102         S.push(t);
103     }
104     root=S.top();S.pop();
105 }
106 int main()
107 {
108     cin>>infix;
109     cin>>n;
110     while(n--){
111         char ch;
112         int v;
113         cin>>ch>>v;
114         val[ch-‘a‘]=v;
115     }
116     infixToPost(infix);         //中缀转后缀
117     cout<<postfix<<endl;
118     build();                    //根据后缀建树
119     ans=cal(root);              //计算值
120     maxDep=findDep(root);       //得到最大深度
121     memset(out,‘ ‘,sizeof(out));
122     //注意到根结点一定是在第一行的2^(maxDep-1)-1的下标位置(别问为什么,因为你看输出出来就是这么诡异),
123     //也就是位于中间的位置,再根据当前层数判断叶子结点放的位置(print函数中)
124     int y=pow(2,maxDep-1)-1;    //根结点在y上的坐标
125     print(root,0,y,y+1>>1);     //形成树形图
126     printTree();
127     cout<<ans;
128 }
时间: 2024-11-08 23:42:11

【数算A】表达式·表达式树·表达式求值的相关文章

Java 计算数学表达式(字符串解析求值工具)

Java字符串转换成算术表达式计算并输出结果,通过这个工具可以直接对字符串形式的算术表达式进行运算,并且使用非常简单. 这个工具中包含两个类 Calculator 和 ArithHelper Calculator 代码如下: import java.util.Collections; import java.util.Stack; /** * 算数表达式求值 * 直接调用Calculator的类方法conversion() * 传入算数表达式,将返回一个浮点值结果 * 如果计算过程错误,将返回一

刁肥宅详解中缀表达式求值问题:C++实现顺序/链栈解决

1. 表达式的种类 如何将表达式翻译成能够正确求值的指令序列,是语言处理程序要解决的基本问题,作为栈的应用事例,下面介绍表达式的求值过程. 任何一个表达式都是由操作数(亦称运算对象).操作符(亦称运算符)和分界符组成的.通常,算术表达式有3种表示: ①中缀(infix)表示:<操作数><操作符><操作数>,如A+B. ②前缀(prefix)表示: <操作符><操作数><操作数>,如+AB. ③后缀(postfix)表示: <操作

序列点在C语言表达式求值中的作用

摘要: 本文开创性地分析了序列点在C语言表达式求值中的作用:序列点左边的操作数要先于其右边的操作数求值.讨论了逗号操作符,.逻辑与操作符&&.逻辑或操作符||和条件操作符?:的问号处需要序列点的原因.举例分析了序列点在表达式求值中的作用. 关键字:序列点 表达式求值 C语言 C语言作为一种主流程序设计语言,许多编程语言如Java.C++.C#都借鉴了它的语法.C语言也是一种很适当的程序设计入门的教学语言,国内大专院校的许多专业都开设了这门课程并且大多将其作为第一门程序设计语言课程,同时C语

四则运算表达式解析和求值(支持括号、小数、小数正负号)

需求分析 四则运算表达式的解析和求值从概念上看是一个逻辑很清晰的过程. 遵循了左结合.优先级差异和括号可以提升优先级这三条规则. 实现思路 实际上只要遍历表达式,将小数和运算符分离到两个序列容器中,在遍历的过程中,考虑左结合和括号对优先级的影响,将相关信息和运算符记录在一起,然后在遍历结束后,按照优先顺序从高到底,从小数序列中拉取两个元素(可能是中间结果的二叉树,实际上小数是一种特例,是左右子树为空的解析完成的二叉树),并且把运算符的两棵子树指向两个元素,把这棵新树放回到小数容器中.不断重复这个

[C] 关于表达式求值

结论是:在一个表达式中,如果两个相邻操作符的执行顺序由它们的优先级决定,如果它们的优先级相同,它们的执行顺序由它们的结合性决定.若出现前述规则描述之外的情形,编译器可以自由决定求值的顺序(只要不违反逗号.&&.||和?:操作符所施加的限制).因此,同一个存在歧义的表达式在不同的编译器下会有不同的运算结果,应该避免写出有歧义的表达式,提高程序的可移植性. 另外,需要注意的是有些表达式的操作数在求值过程中可能需要转换为其他类型,最常见的有整形提升(一种隐式类型转换)和寻常算术转换. 整型值和浮

4132:四则运算表达式求值(栈)

总时间限制: 1000ms 内存限制:  65536kB 描述 求一个可以带括号的小学算术四则运算表达式的值 输入 一行,一个四则运算表达式.'*'表示乘法,'/'表示除法 输出 一行,该表达式的值,保留小数点后面两位 样例输入 输入样例1: 3.4 输入样例2: 7+8.3 输入样例3: 3+4.5*(7+2)*(3)*((3+4)*(2+3.5)/(4+5))-34*(7-(2+3)) 样例输出 输出样例1: 3.40 输出样例2: 15.30 输出样例3: 454.75  思路:先把中缀表

Golang语句中的求值顺序

在Go specs中,有这样三点陈述: 1.变量声明(variable declaration)中的初始化表达式(initialization expressions)的求值顺序(evaluation order)由初始化依赖(initialization dependencies)决定:但对于初始化表达式内部的操作数的求值需要按照2中的顺序:从左到右: 2.在非变量初始化语句中,对表达式.赋值语句或返回语句中的操作数进行求值时,操作数中包含的函数(function)调用.方法(method)调

Swift 之惰性求值

Swift 之惰性求值 在 Haskell 中的函数有一个特性 函数的返回可能是一个块(一个被延迟计算的表达式) 从而引出一个概念 惰性求值 isOdd n = mod n 2 == 1 下面有段 分析 在使用严格求值的语言里,函数的参数总是在应用函数之前被求值.以 isOdd 为例子:子表达式 (1 + 2) 会首先被求值,得出结果 3 .接着,将 3 绑定到变量 n ,应用到函数 isOdd .最后, mod 3 2 返回 1 ,而 1 == 1 返回 True . Haskell 使用了另

表达式求值

表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描写叙述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,近期又学会了一些简单的函数求值,比方,它知道函数min(20,23)的值是20 ,add(10,98) 的值是108等等.经过训练,Dr.Kong设计的机器人卡多甚至会计算一种嵌套的更复杂的表达式. 如果表达式能够简单定义为: 1. 一个正的十进制数 x 是一个表达式. 2. 假设 x 和 y 是 表达式,则 函数min(x,y )也是表达式,其值为x