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

📄 calculator.cpp

📁 表达式计算
💻 CPP
字号:
#include < iostream.h >
#include <fstream.h>
#include < cmath >
#include "Calculator.h"
int isp( char ch )
{//栈内优先数
	int s=0;
	switch (ch)
	{
	   case '=' : s = 0 ;break;
	   case '(' : s = 1 ;break;
       case '^' : s = 7 ;break;
	   case '*' : 
       case '/' : 
	   case '%' : s = 5;break;
	   case '+' : 
	   case '-' : s = 3 ;break;
       case ')' : s = 8 ;break;
	}
    return s;
}

int icp( char ch )
{//栈外优先数
	int s=0;
	switch (ch)
	{
	   case '=' : s = 0 ;break;
	   case '(' : s = 8 ;break;
       case '^' : s = 7 ;break;
	   case '*' : 
       case '/' : 
	   case '%' : s = 4;break;
	   case '+' : 
	   case '-' : s = 2 ;break;
       case ')' : s = 1 ;break;
	}
    return s;
}

void postfix ()
{//将中缀表达式转化为后缀表达式
	stack < char > s(40); char ch , y;//定义栈的对象s,其元素为字符
	s.makeempty(); s.push('=');//栈底放了一个‘#’
	ofstream fout;
	fout.open("datefile.txt",ios::nocreate );//将转化结果输入到文档中
	if (!fout ){cerr << "The  datefile.txt cannot be openend!\n ";}
	while ( cin.get ( ch ) , ch != '=' )//遇到‘)’,需持续退栈,直到遇到‘(’
	{
		if ( ch >= 48 && ch <= 57 ) fout<<ch<<" " ;//是操作数,输出
		else if ( ch == ')')
			for ( y = s.pop() ; y != '(' ; y = s.pop() )fout << y <<" ";//持续输出y,退栈
			else //是操作符
			{
				for ( y = s.pop(); isp( y ) > icp (ch); y=s.pop() ) fout << y<<" ";//isp栈内优先数,icp是栈外优先数
                s.push( y ); s.push( ch );//刚除栈的y再进栈
			} 
	}
	while ( ! s.isempty() ) { y = s.pop(); fout << y<<" ";}
	fout.close ();
}
void Calculator::AddOperand ( double value )
{//将操作数的值入栈
	s.push ( value );
}

bool Calculator :: Get2Operands ( double &left ,double &right )
{//从栈中取出两个操作数
	if ( s.isempty() ){ cerr << "Missing Operand ! \n";return false; }//检查栈是否空
	right = s.pop();//取右操作数
	if ( s.isempty() ){ cerr << "Missing Operand ! \n";return false; }//检查栈是否空
	left = s.pop();//取左操作数
	return true ;
}

void Calculator :: DoOperator ( char op )
{//取操作数,形成操作指令并运算
    double left , right ;//取两个操作数
	bool result;
	result = Get2Operands ( left , right );//若取数成功,进行运算
	if ( result == true )
		switch ( op )
	{
			case '+':  s.push ( left + right ); break ;//加
			case '-':  s.push ( left - right ); break ;//减
			case '*':  s.push ( left * right ); break ;//乘
			case '/':  if ( right == 0.0 ){cerr<<"Dvide by 0 !\n";break;Clear();}//除,若除数为0则报错
				else	{s.push ( left / right ); break ;}//否则计算
			case '^':  s.push ( pow( left , right ) ); break ;//乘幂
	}
	else Clear ();//出错清0
}

void Calculator :: Run ()
{//读入字符串并求一个后缀表达式的值。以 ‘=’结束
	Clear();//清零
	cout<<"please enter expressions,end with \'=\'.\n";//
    postfix ();//将中缀表达式转化为后缀表达式
	char ch ; double newoperand ;
	ifstream infile;
	infile.open( "datefile.txt" ) ;//从文件读入
	if (!infile ){cerr << "The  datefile.txt cannot be openend!\n ";}
	while ( infile >> ch , ch != '=' )
	{
		switch ( ch )
		{
		case '+': 
		case '-':
		case '*':
		case '/':
		case '%':
		case '^': DoOperator ( ch ) ;break;//是操作符,执行计算
		default : infile.putback ( ch );//将字符放回输入流
			infile>> newoperand;//重新读入操作数
			AddOperand ( newoperand );//将操作数放入栈中
			break;
		}
	}
	cout<<"the result of this expression is: "<<s.gettop();//输出结果
	infile.close();
	cout<<endl;
}

void Calculator ::Clear()
{//清空
	s.makeempty();//置空
}

⌨️ 快捷键说明

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