黑框版计算器

不智能的计算器

        最近公司事情不是很多,就像随便写个东西玩玩,可惜想了半天想不到 。最后只能做个自己大学时没做的很简单的程序。也算了了遗憾,可是做起来的时候才发现原来黑框的计算器也不是好做的,无奈只能google,发现了一种方法比较流行,就生成树比如说(1+2)*3呢,就按权值不同生成的树是:


生成树(图比较粗糙啊)

理解是挺好理解的,但是程序写起来确很费事,需要双向链表及二叉树。可是我就是那种很少用数据结构的人,可能编程的时间太短,很多东西都不是很懂。

但是我自己想了个方法,也不知道算不算方法,总之很乱,我自己看都要看半天才可以理解。

好了废话不说了,上代码(很多的可能出现bug的地方都没有处理,所以可能bug很多)

#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>

using namespace std;

#define PI 3.14159265358979
#define EE 2.71828182818281

const string NUM = "0123456789.";
const string OPERATION = "+-*/";

namespace MyCalc
{
	class Fun
	{
	public:
		Fun(string o, double lVal, double rVal):op(o), lValue(lVal), rValue(rVal){}
		static string FUN[];
		double calc();

	private:
		string op;
		double lValue;
		double rValue;

	};

	string Fun::FUN[] = {"!","sin","cos","tan","log","ln","C","A","^","-"};

	int factorial(int n) //阶乘函数
	{
		int i,s=1;
		for(i=1;i<=n;i++)
			s*=i;
		return s;
	}

	int C(int a,int b)
	{
		return factorial(a)/(factorial(b)*factorial(a-b));
	}

	int A(int a,int b)
	{
		return factorial(a)/factorial(b);
	}

	double Fun::calc() //计算系统函数的值
	{
			if(op=="!")
				return factorial(lValue);
			if(op=="sin")
				return sin(rValue/180*PI);
			if(op=="cos")
				return cos(rValue/180*PI);
			if(op=="tan")
				return tan(rValue/180*PI);
			if(op=="log")
				return log10(rValue);
			if(op=="ln")
				return log10(rValue)/log10(EE);
			if(op=="C")
				return C(lValue,rValue);
			if(op=="A")
				return A(lValue,rValue);
			if(op=="^")
				return pow(lValue,rValue);
			if(op=="-")
				return -rValue;
			else
			{
				string err="暂时没有函数"+op;
				MessageBox(NULL,err.c_str(),"错误",MB_OK);
				return 0;
			}
	}
	
}


#include "MyCalc.h"

typedef struct _Operation
{
	char cOperation;
	int iWeight;
}Operation, *POperation;

bool IsNum(char c)
{
	if(NUM.find(c) != string::npos)
		return true;
	return false;
}

bool IsOperation(char c)
{
	if(OPERATION.find(c) != string::npos)
		return true;
	return false;
}

//others are treated as function. 
bool IsFun(char c)
{
	if(!IsNum(c) && ! IsOperation(c) && c != 
               '(' && c != ')' && c != ' ')
		return true;
	return false;
}

double calc(double lValue, double rValue, char operation)
{
	switch(operation)
	{
	case '+':
		return rValue + lValue;
	case '-':
		return lValue - rValue;
	case '*':
		return lValue * rValue;
	case '/':
		return lValue / rValue;
	default:
		return 0;
	}
}

//Getting a number from input string
void getNum(string inputStr, int &i, int &valuesNum, double dValues[])
{
	int iPoint = 0;
	dValues[valuesNum] = 0.0;
	while (i < inputStr.length())
	{
		if(inputStr[i] == '.')
		{
			iPoint++;
			i++;
			continue;
		}

		if(iPoint == 0)
			dValues[valuesNum] *= 10;
		dValues[valuesNum] += (inputStr[i] - '0')*pow(10.0, -iPoint);
		i++;

		if(iPoint != 0)
			iPoint++;

		if(!IsNum(inputStr[i]))
		{
			i--;
			valuesNum++;
			return;
		}
	}
}

//deal with functions
void HandlingFunction(string inputStr, int &valuesNum, double dValues[], int &i)
{
	string op = "";
	while(i++)
	{
		if(i < inputStr.length())
		{
			if(IsOperation(inputStr[i]))
			{
				MyCalc::Fun * fun = new MyCalc::Fun(op, dValues[valuesNum - 1], 0.0);
				dValues[valuesNum - 1] = fun->calc();

				break;
			}
			else if(IsNum(inputStr[i]))
			{
				getNum(inputStr, i, valuesNum, dValues);
				MyCalc::Fun *fun = new MyCalc::Fun(op, dValues[valuesNum -2], dValues[-1]);
				dValues[valuesNum -1] = fun->calc();

				valuesNum --;
				break;
			}
		}
		else
		{
			MyCalc::Fun * fun = new MyCalc::Fun(op, dValues[valuesNum - 1], 0.0);
			dValues[valuesNum - 1] = fun->calc();
			break;
		}
		op += inputStr[i];
	}
}

double GetValue(string inputStr)
{
	int iWeigth = 0;
	int l_point = 0;
	double dValues[] = {0.0, 0.0, 0.0};
	int valuesNum = 0;
	POperation pOperation = (POperation)malloc(sizeof(Operation) * 4);

	string op = "";


	for (int i = 0;i < inputStr.length();i++)
	{
		if(inputStr[i] == '(')
		{
			iWeigth += 3;
			continue;
		}
		else if(inputStr[i] == ')')
		{
			iWeigth -= 3;
			if(iWeigth < 0)
			{
				MessageBox(NULL, "Inputting brackets are not matched!", "MyCalc", MB_OK);
				return 0;
			}

			if(valuesNum > 1 && (i + 1) < inputStr.length() && IsFun(inputStr[i + 1]))
			{
				dValues[0] = calc(dValues[0], dValues[1], pOperation[-1].cOperation);
				valuesNum--;
				HandlingFunction(inputStr, valuesNum, dValues, i);
			}
			continue;
		}

		else if(IsNum(inputStr[i]))
		{
			getNum(inputStr, i, valuesNum, dValues);
		}
		else if(IsOperation(inputStr[i]))
		{
			int add_weight = 0;
			if(inputStr[i] == '+' || inputStr[i] == '-')
				add_weight = 1;
			else if(inputStr[i] == '*' || inputStr[i] == '/')
				add_weight = 2;
			pOperation->cOperation = inputStr[i];
			pOperation->iWeight = add_weight + iWeigth;
			pOperation++;
		}

		//treat as a function
		if((i + 1) < inputStr.length() && IsFun(inputStr[i + 1]))
		{
			HandlingFunction(inputStr, valuesNum, dValues, i);
		}

		if(valuesNum == 3)
		{
			if(pOperation[-2].iWeight > pOperation[-1].iWeight)
			{
				dValues[0] = calc(dValues[0], dValues[1], pOperation[-2].cOperation);
				dValues[1] = dValues[2];
				pOperation[-2] = pOperation[-1];

			}
			else
			{
				dValues[1] = calc(dValues[1], dValues[2], pOperation[-1].cOperation);
			}
			pOperation--;
			valuesNum = 2;
		}

	}

	pOperation--;
	double lastValue = 0.0;
	if(valuesNum == 2)
		lastValue = calc(dValues[0], dValues[1], pOperation->cOperation);
	else
		lastValue = dValues[0];
	free(pOperation);
	return lastValue;
}

void main()
{
	string exp;

	ifstream infile("c:\\test.txt");
	while(getline(infile,exp))
	{
		if(exp=="")
			continue;

		cout<<exp<<" = "<<GetValue(exp)<<endl;
	}
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值