⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expression.cpp

📁 用C++编写的一个计算器
💻 CPP
字号:
//Expression.cpp
#include <iostream>
#include <cstdlib>
#include "Expression.h"
using namespace std;

Expression::Expression(char* c):OPTR(20),OPND(50){
	char *tmp = c;
	while(*tmp) tmp++;
	*(tmp++) = '=';
	*tmp = '\0';
	s = c;
}

char Expression::Precede(OptrType r1,OptrType r2){
	//Define the Precedence Relationship between operator
	switch(r1){
	case'(':
		switch(r2){
		case')': return '#';
		case'=': return '@';
		default: return '<';
		}
		case')':
			switch(r2){
			case'(': return '@';
			default: return '>';
		}
		case'=':
			switch(r2){
			case'=': return '#';
			case')': return '@';
			default: return '<';
			}
			case'*':
			case'/':
				switch(r2){
				case'(': return '<';
				default: return '>';
				}
				case'+':
				case'-':
					switch(r2){
					case'*':
					case'/':
					case'(': return '<';
					default: return '>';
					}
					default: return '@';
	}
}

int Expression::In(char c){
	//Judge whether the charactor is a operator or a operand
	//If the charactor is a operand,change it into numeral
	//If it is a operator ,return -1
	if(c>='0'&&c<='9') return c-'0';
	if(c == '.') return -2;
	return -1;
}

OpndType Expression::Operate(OpndType x,
							 OptrType o,OpndType y){
	switch(o){
	case'+': return x+y;
	case'-': return x-y;
	case'*': return x*y;
	case'/': return x/y;
	default: return 0;
	}
}

OpndType Expression::calPostExpression(void){
	OptrType c,e,x,oper;
	OpndType a,b,num = 0;
	OpndType frac = 0,rank = 1;
	int opnd,i=0,j=0;
	bool flag = false;//judge whether tow or more operands aer continous input
	                  //change into false while a operator is input
	bool leap = true;//judge whether tow or more operators are continous input
	                 //true mean yes
	bool point = false;//judge whether point exists
					   //false means point does not exist
	OPTR.Push('=');
	OPND.Push(0);
	c=s[i];
	while(c!='='||OPTR.GetTop(e)&&e!='='){
		if(-1 !=(opnd = In(c))){
			//If there are several numerals together
			//Change them into a numeral
			if(-2 == opnd){ 
				point = true;
				c = s[++i];
				continue;
			}
			if(point){
				frac = opnd+10*frac;
				rank = rank*10;
				c = s[++i];
			}
			else{
				num = opnd + 10*num;
				c = s[++i];
				flag = true;
				leap = false;
				}
		}
		else {
			if(flag){
				//If no numeral is inputed
				//stop pushing numeral into the stack
				frac = frac/rank;
				num = num+frac;
				OPND.Push(num);
				num = 0;frac = 0;
				rank = 1;
				flag = false;point = false;
			}
			OPTR.GetTop(e);
			if(leap&&'(' == e)
				if('-' == c){
					OPND.Push(0);
					leap = false;
				}
			switch(Precede(e,c)){
			case'<':
				OPTR.Push(c);
				c = s[++i];
				leap = true;
				break;
			case'#':
				OPTR.Pop(x);
				c = s[++i];
				break;
			case'>':
				OPTR.Pop(oper);
				OPND.Pop(b);
				OPND.Pop(a);
				OPND.Push(Operate(a,oper,b));
				break;
			default:
				cout<<"Error!"<<endl;
				exit(1);
			}
		}
	}
	OPND.Pop(a);
	return a;
}

/*======= The Precedence Relation between Operators =========
 *     R2  |   +      -      *      /      (      )      =
 *     R1 -|-------------------------------------------------  
 *     +   |   >      >      <      <      <      >      >
 *     -   |   >      >      <      <      <      >      >
 *     *   |   >      >      >      >      <      >      >
 *     /   |   >      >      >      >      <      >      >
 *     (   |   <      <      <      <      <      #      _
 *     )   |   >      >      >      >      _      >      >
 *     =   |   <      <      <      <      <      _      #
 *
 * This list shows which operator operates operands first  */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -