计算带括号的数值表达式

 

题目:

输入一串数值算术表达式( 如:34+5-(8+4)*6 ,计算机编程实现对该表达式的树形存储(即:去除括号),并输出表达式的结构树和相应的前缀表达式和后缀表达式,以及完成求值运算。

算法:

共分为5个文件,4个头文件,一个主函数.

“jiedian.h”

 #include

using namespace std;

const int MAX=100;//最大节点数

const int N=100;//最大字符串长度

//定义节点类

union zifu_shuzi

{

double shuzi;

char zifu;

};

class jiedian

{

private:

zifu_shuzi j;

public:

jiedian *left,*right;

int flag;

jiedian();

void create(char);

void create(double);

void dele();

void show();//输出接点存储的某个数据

};

jiedian::jiedian()

{

j.shuzi=NULL;

flag=-1;

}

void jiedian::dele()

{

j.shuzi=j.zifu=NULL;

}

void jiedian::create(char s)

{

flag=1;

j.zifu=s;

}

void jiedian::create(double s)

{

flag=0;

j.shuzi=s;

}

void jiedian::show()

{

if(flag==1)

cout<<j.zifu<<" ";

else

cout<<j.shuzi<<" ";

}

 

“tree.h”

#include"zhuanhuan.h"

class tree

{

public:

void create(char *);//树形存储

void show();//输出前缀

tree();

private:

jiedian jd[MAX];

int num;

void DFS(jiedian*);//搜索,用于输出前缀表达式

};

tree::tree()

{

num=0;

for(int i=0;i

jd[i].flag=-1,jd[i].left=NULL,jd[i].right=NULL;

}

void tree::create(char *s)

{

s=fun(s);

my_zhan Z;

for(int i=0;is);i++)

{

if(s[i]==' ')

continue;

else if(s[i]>='0'&&s[i]<='9')

{

double temp=s[i++]-'0';

while(s[i]>='0'&&s[i]<='9')

{

temp*=10;

temp+=(s[i]-'0');

i++;

}

if(s[i]=='.')

{

int lag=1;

i++;

while (s[i]>='0' && s[i]<='9')

{

temp+=(double)s[i]/(lag*10);

lag*=10;

i++;

}

}

jd[num].create(temp);

Z.in((double)num);

num++;

}

else 

{

jd[num].create(s[i]);

jd[num].right=&jd[(int)Z.out_shuzi().shuzi];

jd[num].left=&jd[(int)Z.out_shuzi().shuzi];

Z.in(double(num));

num++;

}

}

num--;//存储根节点

}

void tree::show()

{

DFS(&jd[num]);

}

void tree::DFS(jiedian* m)

{

if(!m) return;

if(m->left!=NULL && m->right!=NULL)

{

m->show();

DFS(m->left);

DFS(m->right);

}

else

{

m->show();

DFS(m->right);

}

}

“zhan.h”

#include"jiedian.h"

//定义栈及栈操作

class my_zhan

{

private:

jiedian j[MAX];

zifu_shuzi shuzi[MAX];

int flag;//字符数字 或者 是节点,1为字符、数字 2为节点

int num;//当前栈内元素个数

public:

my_zhan();

void in(jiedian);//节点入栈

void in(double);//数字入栈

void in(char);//字符入栈

jiedian out_jiedian();//出栈

zifu_shuzi out_shuzi();//出栈

zifu_shuzi pop_shuzi();

jiedian pop_jiedian();

int get_num();//返回num

};

my_zhan::my_zhan()

{

flag=0;

num=0;

memset(shuzi,NULL,sizeof(shuzi));

}

void my_zhan::in(double p)

{

flag=1;

shuzi[num++].shuzi=p;

}

void my_zhan::in(char p)

{

flag=1;

shuzi[num++].zifu=p;

}

void my_zhan::in(jiedian p)

{

flag=2;

j[num++]=p;

}

jiedian my_zhan::out_jiedian()

{

jiedian *p=new jiedian;

if(flag==2)

{

if(num!=0)

{

*p=j[--num];

j[num].dele();

return *p;

}

else

return *p;

}

else

return *p;

}

zifu_shuzi my_zhan::out_shuzi()

{

zifu_shuzi *p=new zifu_shuzi;

p->zifu='#';

if(flag==1)

{

if(num!=0)

{

*p=shuzi[--num];

shuzi[num].zifu=NULL;

shuzi[num].shuzi=NULL;

return *p;

}

else

return *p;

}

else

return *p;

}

zifu_shuzi my_zhan::pop_shuzi()

{

return shuzi[num-1];

}

jiedian my_zhan::pop_jiedian()

{

return j[num-1];

}

int my_zhan::get_num()

{

return num;

}

“zhuanhuan.h”

#include"zhan.h"

//中缀转换成后缀,主函数:fun()

//增加求值功能 calc

struct pp

{

char s1;

char s2;

};

pp s[4];//运算符优先级表

void create();//打表

bool panduan(char s,char p);//判断运算符优先级 s>=p 为1  s

int help_panduan(char s);//s在运算符优先级表的哪一个位置

double calc();//求值

void create()

{

pp a,b,c,d;

d.s1='#',d.s2=NULL;

a.s1='*',a.s2='/';

b.s1='+',b.s2='-';

c.s1='(',c.s2=NULL;

s[0]=d;

s[1]=b;

s[2]=a;

s[3]=c;

}

char* fun(char *s)//中缀转换成后缀

{

create();

my_zhan Z;

char ans[N];

memset(ans,NULL,sizeof(ans));

int len=0;//后缀表达式长度

bool flag=0;//是否要添加括号

for(int i=0;i

{

if((s[i]>='0' && s[i]<='9')|| s[i]=='.' )

{

 

if(flag==1) ans[len++]=' ',flag=0;

ans[len++]=s[i];

}

else if(s[i]==' ')

continue;

else if(s[i]=='(')

{

Z.in(s[i]);

flag=1;

}

else if(s[i]==')')

{

while(Z.pop_shuzi().zifu!='(')

{

ans[len++]=' ';

ans[len++]=Z.out_shuzi().zifu;

}

ans[len++]=' ';

Z.out_shuzi().zifu;

}

else 

{

while(panduan(s[i],Z.pop_shuzi().zifu)==0)

{

ans[len++]=' ';

ans[len++]=Z.out_shuzi().zifu;

}

Z.in(s[i]);

flag=1;

}

}

while(Z.get_num()!=0)

{

ans[len++]=' ';

ans[len++]=Z.out_shuzi().zifu;

}

return ans;

}

bool panduan(char s,char p)

{

if(help_panduan(s)>help_panduan(p))

return 1;

else 

return 0;

}

int help_panduan(char p)

{

for(int i=0;i<3;i++)

{

if(s[i].s1==p || s[i].s2==p)

return i;

}

return -1;

}

double calc(char *s)

{

s=fun(s);

my_zhan Z;

for(int i=0;i

{

if(s[i]==' ')

continue;

else if(s[i]>='0'&&s[i]<='9')

{

double temp=s[i++]-'0';

while(s[i]>='0'&&s[i]<='9')

{

temp*=10;

temp+=(s[i]-'0');

i++;

}

if(s[i]=='.')

{

int lag=1;

while (s[i]>='0' && s[i]<='9')

{

temp+=(double)s[i]/(lag*10);

lag*=10;

i++;

}

}

Z.in(temp);

}

else 

{

char f=s[i];

double temp2=Z.out_shuzi().shuzi;

double temp1=Z.out_shuzi().shuzi;

switch (f)

{

case '*':Z.in(temp1*temp2);break;

case '-':Z.in(temp1-temp2);break;

case '/':Z.in(temp1/temp2);break;

case '+':Z.in(temp1+temp2);break;

default:

break;

}

}

}

int i=0;

return Z.out_shuzi().shuzi;

}

 

“main.cpp”

#include"tree.h"

int main()

{

while(1)

{

char s[N];

gets(s);

cout<<"表达式的值为:";

cout<<calc(s)<<endl;

cout<<"后缀形式:";

puts(fun(s));

tree b;

b.create(s);

cout<<"前缀形式:";

b.show();

cout<<endl;

}

}

 

 

 

### 括号中缀表达式求值方法 #### 方法概述 为了计算括号的中缀表达式的值,可以采用栈的数据结构来辅助完成这一过程。具体来说,可以通过两个栈分别存储操作数和运算符[^4]。其中,操作数栈用于保存数值,而运算符栈则负责管理各种算术运算符及其优先级。 在处理过程中,如果遇到左括号,则将其直接压入运算符栈;当遇到右括号时,需持续弹出运算符并执行相应的计算直到找到匹配的左括号为止。此外,在遍历整个字符串的过程中还需要注意比较当前运算符与栈顶运算符之间的优先关系,从而决定是否立即进行计算或者继续将新的运算符压入栈中。 以下是详细的算法解析以及示例代码: #### 算法解析 1. 初始化两个空栈:`opstack` (operator stack) 和 `numstack` (number stack)。 2. 遍历输入的中缀表达式中的每一个字符: - 如果该字符是一个数字,则读取完整的连续数字序列作为整体的一个操作数,并将其推送到 `numstack` 中。 - 若为加减乘除等基本运算符 (+, -, *, /),应遵循以下原则: - 当前运算符具有较高或相等于栈顶运算符的优先级时,先从两栈取出相应元素做一次运算再把结果存回 `numstack` ,之后才可考虑将此新运算符加入到 `opstack` 。 - 否则只需简单地把它放入 `opstack`. 3. 特殊情况——括号: - 左括号总是被无条件地送至 `opstack`; - 右括号触发内部循环直至发现对应的左括号位置之前的所有中间项均已完成各自的子任务(即完成了局部区域内的全部可能的小型四则混合运算), 并且最后一步还需记得移除那个已经配对成功的左括号本身. 4. 完全扫描结束后仍可能存在尚未解决的部分留在堆栈里头,因此要再次确认一遍剩余的内容是否有待进一步简化组合成最终答案形式. #### 示例代码 下面提供了一个基于上述描述编写的 Python 函数用来演示如何通过栈机制评估含括号在内的标准数学表达式的实际价值: ```python def evaluate_expression(expression): precedence = {'+':1,'-':1,'*':2,'/':2} def apply_operator(operators, values): operator = operators.pop() right = values.pop() left = values.pop() if operator == '+': values.append(left + right) elif operator == '-': values.append(left - right) elif operator == '*': values.append(left * right) elif operator == '/': values.append(int(left / float(right))) def greater_precedence(op1, op2): return precedence[op1] >= precedence[op2] operators = [] operands = [] i = 0 while i < len(expression): char = expression[i] if char.isdigit(): j = i while(j<len(expression) and expression[j].isdigit()): j +=1 operands.append(int(expression[i:j])) i=j elif char == '(': operators.append(char) elif char == ')': while operators[-1]!='(' : apply_operator(operators,operands) operators.pop() elif char in "+-*/": while(len(operators)!=0 and operators[-1]!= '('and greater_precedence(operators[-1],char)): apply_operator(operators,operands) operators.append(char) i+=1 while len(operators)>0: apply_operator(operators,operands) return operands[0] expression="(2+(3*(8/4)))" print(evaluate_expression(expression)) # Output should be 10 as per given example. ``` ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值