表达式(二)

后缀表达式由于其特殊性只需要操作数栈,不需要运算符栈,每当出现运算符就说明是对前面两个操作数进行操作

#include<bits/stdc++.h>
using namespace std;
char tok[30][20];
int tok_max;
int pos=1;

int main(){
	tok_max=0;
	int num1=0;
	for(;;){
		int c=getchar();
		if(c=='@')break;
		if(c=='+'||c=='-'||c=='*'||c=='/'){
			tok[++tok_max][0]=c;
		}else if(c=='.'){
			sprintf(tok[++tok_max],"%d",num1);
			num1=0;
		}else{
			num1=num1*10+(c-'0');
		}
	}
//	for(int i=1;i<=tok_max;i++){
//		puts(tok[i]);
//	}

	stack<int>st;
	for(int i=1;i<=tok_max;i++){
		//操作数
		if(isdigit(*tok[i])){ 
			int num2;
			sscanf(tok[i],"%d",&num2);
			st.push(num2);
		}
		//运算符
		else if(*tok[i]=='+'){  
			int num3=st.top();st.pop();
			int num4=st.top();st.pop();
			int num5=num4+num3;
			st.push(num5);
		}
		else if(*tok[i]=='-'){
			int num3=st.top();st.pop();
			int num4=st.top();st.pop();
			int num5=num4-num3;
			st.push(num5);
		}
		else if(*tok[i]=='*'){
			int num3=st.top();st.pop();
			int num4=st.top();st.pop();
			int num5=num4*num3;
			st.push(num5);
		}
		else if(*tok[i]=='/'){
			int num3=st.top();st.pop();
			int num4=st.top();st.pop();
			int num5=num4/num3;
			st.push(num5);
		}
		
		
	}
	
	printf("%d\n",st.top());
	return 0;
}

前缀表达式

前缀表达式用栈写相对麻烦,但由于运算符前置,可以方便地将其转化为二叉树,递归实现

#include<bits/stdc++.h>
using namespace std;
char tok[6000][30];
int tok_max;
int pos=1;

struct TREE{
	double val;
	char op;
	struct TREE *l,*r;
}tr;

void build_tree(struct TREE *tr){
	if(isdigit(*tok[pos])){
		sscanf(tok[pos],"%lf",&(tr->val));
		//tr->val=atof(tok[pos]);
		pos++;
		tr->l=NULL;tr->r=NULL;
		return;
	}
	else{
		tr->op=*tok[pos];
		pos++;
		tr->l=(struct TREE*)malloc(sizeof(struct TREE));
		tr->r=(struct TREE*)malloc(sizeof(struct TREE));
		build_tree(tr->l);build_tree(tr->r);
		return;
	}
}
/*
void x(struct TREE *tr){
	if(tr==NULL)return;
	
	x(tr->l);
	if(tr->l==NULL && tr->r==NULL){
		printf("%f ",tr->val);
	}else{
		printf("%c ",tr->op);
	}
	x(tr->r);
}*/

double calc(struct TREE *tr){
	if(tr->l==NULL && tr->r==NULL){ //是操作数
		return tr->val;
	}
	else{
		if(tr->op=='+')return calc(tr->l)+calc(tr->r);
		if(tr->op=='-')return calc(tr->l)-calc(tr->r);
		if(tr->op=='*')return calc(tr->l)*calc(tr->r);
		if(tr->op=='/')return calc(tr->l)/calc(tr->r);
	}
}

int main(){
	tok_max=1;
	for(;;){
		int num=scanf("%s",tok[tok_max]);
		if(num==EOF)break;
		tok_max++;
	}
	
	build_tree(&tr);
	
	//x(&tr);
	
	double ans=calc(&tr);
	printf("%f\n",ans);
	return 0;
}

PS:以上代码经常出现*tok[i]一类的表达,因为tok[i]可看做指向数组的指针,*tok[i]等价于tok[i][0],写起来简洁易懂

posted @ 2024-08-08 15:21  计算机知识杂谈  阅读(7)  评论(0编辑  收藏  举报