表达式树及其变体,以及我是如何借着个原理实现简易计算器的功能的

本文介绍了如何基于表达式树的原理,修改并优化算法,实现了一个能够处理数学表达式的简易计算器。通过删除不必要的存储功能,专注于计算,将算法应用到实际程序中,实现了输入表达式得到答案的目标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本题来源:《算法竞赛入门》第11章11.11.2

本题给的解法:

核心代码:

int build_tree(string exp,int l,int r)
{
	cout<<"l="<<l<<"\tr="<<r<<endl;
	int c1,c2,p,u;
	c1=-1;
	c2=-1;
	p=0;
	if(r-l<=1)
	{
		u=++cnt;
		chl[u]=chr[u]=0;
		operation[u]=exp[x];
		return -1;
	}
	for(int i=l;i<r;++i)
	{
		switch(exp[i])
		{
			case '(':++p;break;
			case ')':--p;break;
			case '+': case '-': if(!p)c1=i;break;
			case '*': case '/': if(!p)c2=i;break;
		}
	}
	if(c1<0)
		c1=c2;
	if(c1<0)
		return build_tree(exp,l+1,r-1);
	u=++cnt;
	chl[u]=build_tree(exp,l,c1);
	chr[u]=build_tree(exp,c1+1,r);
	operation[u]=exp[c1];
	return u;
}


我为了让这个代码对我更加友好写,对这个代码做了一下修改,改完之后的完整代码是这样的:

#include<iostream>
#include<fstream>
#include<string>
#include<cstring>
using namespace std;

ifstream fin("ExpressionTree.in");

#define MAXSIZE 100
string exp;
int chl[MAXSIZE],chr[MAXSIZE];
char operation[MAXSIZE];
int cnt=0;

int build_tree(string exp,int l,int r)
{
	cout<<"l="<<l<<"\tr="<<r<<endl;
	int c1,c2,p,u;
	c1=-1;
	c2=-1;
	p=0;
	if(r-l<=1)
	{
		u=++cnt;
		chl[u]=chr[u]=-1;
		operation[u]='#';
		return -1;
	}
	for(int i=l;i<r;++i)
	{
		switch(exp[i])
		{
			case '(':++p;break;
			case ')':--p;break;
			case '+': case '-': if(!p)c1=i;break;
			case '*': case '/': if(!p)c2=i;break;
		}
	}
	if(c1<0)
		c1=c2;
	if(c1<0)
		return build_tree(exp,l+1,r-1);
	u=++cnt;
	chl[u]=build_tree(exp,l,c1);
	chr[u]=build_tree(exp,c1+1,r);
	operation[u]=exp[c1];
	return u;
}

int main()
{
	memset(operation,0,sizeof(operation));
	memset(chl,0,sizeof(operation));
	memset(chr,0,sizeof(operation));
	fin>>exp;
	build_tree(exp,0,exp.size());
	for(int i=1;i<=cnt;++i)
		cout<<operation[i]<<"\t";
	cout<<endl;
	return 0;
}


改完之后我为了实现这个代码的完整功能,借着个算法提出了个目标:输入一个数学表达式,输出答案。然后对上面的核心代码进行修改,添加我需要的计算功能,删除我不需要的储存功能,就写出了下面的完整程序:

#include<iostream>
#include<fstream>
#include<string>
#include<cstring>
using namespace std;

ifstream fin("../Data/CalExp.in");

#define MIN -32767
string str;
int result;

int checkVadality(int val,int l,int r)
{
	if(val==MIN)
	{
		val=0;
		for(int i=l;i<r;++i)
			if(str[i]>='0'&&str[i]<='9')
				val=val*10+(str[i]-'0');
	}
	return val;
}

int calc(string s,int l,int r)
{
	int c1=-1,c2=-1,p=0;
	int s1=0,s2=0;
	if(r-l<=1)
	{
		return MIN;
	}
	for(int i=l;i<r;++i)
	{
		switch(s[i])
		{
			case '(':++p;break;
			case ')':--p;break;
			case '+': case '-':if(!p)c1=i;break;
			case '*': case '/':if(!p)c2=i;break;
		}
	}
	if(c1<0)
		c1=c2;
	if(c1<0)
	{
		return calc(s,l+1,r-1);
	}
	s1=calc(s,l,c1);
	s2=calc(s,c1+1,r);
	s1=checkVadality(s1,l,c1);
	s2=checkVadality(s2,c1+1,r);
	if(s[c1]=='+')
	{
		return s1+s2;
	}
	else if(s[c1]=='-')
	{
		return s1-s2;
	}
	else if(s[c1]=='*')
	{
		return s1*s2;
	}
	else if(s[c1]=='/')
	{
		return s1/s2;
	}
}

int main()
{
	while(cin>>str)
		cout<<calc(str,0,str.size());
	return 0;
}

这样一个完整的,具备初级加减乘除功能的计算器程序就实现了。


然后我发现,这个算法和我之前写过的一个有相似之处。Complicated Expression。这个代码可以用这个算法来替换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值