逆波兰运算器浮点求值(c++版本)

//--calculator_of_double.h   //----头文件

/*----------浮点求值运算器-----------*/

/*-------框架--------*/
/*
1.判断匹配
	a.搞个临时栈tmpS存所有()
	b.判断tmpS的匹配
		遇到(进
		遇到)
			若空,则假
			若非空,即是(,则弹(;ch++
		返回tmpS空即是匹配真
2.总函数
	1.若数字则s++,并后续,转double,push
	2.若字符switch优先级,分别处理
		A.<,push
		B.=,pop,s++
		C,>,双目运算,push
		
*/
#ifndef Calculator_of_double_
#define Calculator_of_double_

#include<stack>
using namespace std;

class CalculatorOD{
	const char * ExpArray;		//----输入的表达式s.assign(cp)用c指针串替换
	stack<double> TmpDoubS;		//----double临时变动栈
	stack<char> TmpSymbolS;		//----临时运算符栈;
public:
	CalculatorOD(const char*);
	bool JudgeMarray();						//----检测括号配对情况
	void Calculat();
	char OrderBetween(char, char);			<span style="white-space:pre">		</span>//----求优先级
	double GetResult(double, char, double);	<span style="white-space:pre">			</span>//----双目求值
	int factorial(int);						//----单目阶乘
};
#endif // !Calculator_of_double_



//----calculator_of_double.cpp  //----定义文件

#include"calculator_of_double.h"
#include<iostream>
#include<stack>
#include<ctype.h>
#include<stdlib.h>
#include<math.h>
#include<stdio.h>

CalculatorOD::CalculatorOD(const char *chPtr){
	ExpArray = chPtr;
	printf("\n输入的是:	%s\n", ExpArray);
	Calculat();
}

bool CalculatorOD::JudgeMarray(){
	stack<char> TmpS;

	for (int i = 0; ExpArray[i] != '\0'; i++){
		if (ExpArray[i] == '(')
			TmpS.push(ExpArray[i]);
		else if (ExpArray[i] == ')'){
			if (!TmpS.empty())
				TmpS.pop();
			else
				return false;
		}
	}

	return TmpS.empty();
}

void CalculatorOD::Calculat(){
	if (!JudgeMarray()){
		cout << "输入不配对!\n"<<endl;
		return;
	}

	TmpSymbolS.push('\0');

	for (int i = 0, j = 0; !TmpSymbolS.empty();)
	{
		char TmpStr[100/*sizeof(ExpArray) / sizeof(ExpArray[0])*/];					//----存储浮点字符串;

		if (!isdigit(ExpArray[i])){			//----跳过非浮点
			switch (OrderBetween(TmpSymbolS.top(), ExpArray[i]))
			{
			case '<':
				TmpSymbolS.push(ExpArray[i++]); 
				break;
			case '=':
				TmpSymbolS.pop();
				i++;
				break;
			case '>':
				double TemD1 = TmpDoubS.top(); TmpDoubS.pop();
				char TemSbl = TmpSymbolS.top(); TmpSymbolS.pop();

				if (TemSbl == '!')
					TmpDoubS.push(factorial(static_cast<int>(TemD1)));
				else{
					double TemD2 = TmpDoubS.top(); TmpDoubS.pop();
					TmpDoubS.push(GetResult(TemD1, TemSbl, TemD2));
				}
				break;
			}
			
		}

		while (isdigit(ExpArray[i]) || ExpArray[i] == '.')
		{
			TmpStr[j++] = ExpArray[i++];	<span style="white-space:pre">		</span>//----复制
			TmpStr[j] = '\0';				//----每个字符后添加'\0'

			if (!isdigit(ExpArray[i]) && ExpArray[i] != '.'){
				TmpDoubS.push(atof(TmpStr));<span style="white-space:pre">		</span>//----转化为浮点存栈里,atof(char*p以空NULL结尾)
				j = 0;					//----继续没串头0索引开始
				//printf("%15.5lf", TmpDoubS.top());
			}
		}
	}
	int ival = 5;
	printf("求得的结果是:%15.8lf\n\n", TmpDoubS.top());
}

char CalculatorOD::OrderBetween(char chStack, char chNew){
	const char SymbolSheet[10][10] =   // 运算符优先等级 [栈顶][ 当前]
		//  |--------------- 当前运算符--------------|		
	{ '+', '-', '*', '/', '^', '!', '(', ')', '\0', '0'
	, '>', '>', '<', '<', '<', '<', '<', '>', '>', '+'	// + -
	, '>', '>', '<', '<', '<', '<', '<', '>', '>', '-'	// - |
	, '>', '>', '>', '>', '<', '<', '<', '>', '>', '*'	// * 栈
	, '>', '>', '>', '>', '<', '<', '<', '>', '>', '/'	// / 顶
	, '>', '>', '>', '>', '>', '<', '<', '>', '>', '^'	// ^ 运
	, '>', '>', '>', '>', '>', '>', '<', '>', '>', '!'	// ! 算
	, '<', '<', '<', '<', '<', '<', '<', '=', ' ', '('	// ( 符
	, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ')'	// ) |
	, '<', '<', '<', '<', '<', '<', '<', ' ', '=', '\0'	// \0--
	};

	char chS = chStack;//'(';//----栈
	char chCur = chNew;// ')';//----当前
	int X, Y;

	for (int i = 0; i <= 9; i++)
	if (SymbolSheet[i][9] == chS){
		X = i; break;
	}
	for (int i = 0; i <= 9; i++)
	if (SymbolSheet[0][i] == chCur){
		Y = i; break;
	}

	/*cout << endl << X << ',' << Y << endl;
	cout << SymbolSheet[X][Y] << endl;*/			//----测试用
	return SymbolSheet[X][Y];
}

double CalculatorOD::GetResult(double D2, char Syb, double D1){
	switch (Syb)
	{
	case'+':
		return D1 + D2;
	case'-':
		return D1 - D2;
	case'/':
		return D1 / D2;
	case'*':
		return D1 * D2;
	case'^':
		return pow(D1, D2);
	/*default:
		return 0;*/
	}
	return 0;//----无意义的,防止编译警告无全部return
}

int CalculatorOD::factorial(int ival){
	if (ival == 0)
		return 1;
	return ival*factorial(ival - 1);
}

//----main.cpp--//----程序入口文件

#include<conio.h>
#include"calculator_of_double.h"
#include<iostream>
using namespace std;

int main(){
	CalculatorOD calA("32^(1/5)^(1/2)");
	CalculatorOD calB("(1*(3+2)-3)/2)");
	CalculatorOD calC("32.1^(1/5.09)^(1.19/2.13)");
	CalculatorOD calD("(1+2^3!-4)*(5!-(6-(7-(89-0!))))");

	return _getch();
}/*--------以下可实现---------
 "32^(1/5)^(1/2)"			得到1.41
 "(1+2^3!-4)*(5!-(6-(7-(89-0!))))"  <span style="white-space:pre">	</span>得到2013
 "32.1^(1/5.09)^(1.19/2.13)"		得到1.46338

 ------以下风格不可实现-------
 32^(-5)
 -3+1
 */







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值