搜索
查看: 1240|回复: 4
打印 上一主题 下一主题

[原创] 自编(还算比较高级)计算器程序

[复制链接]
跳转到指定楼层
楼主
发表于 2013-11-10 16:10:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 981013 于 2013-11-10 16:34 编辑

自己写了个计算器,打表达式进去就能计算
附上代码
[code=Cpp width=740px]//caculator.h
#ifndef CACULATOR_H
#define CACULATOR_H
#include <mylib.h>
#include <cmath>
#define DEBUG 0
using std::cerr;
using std::endl;
using mine::stack;
int opl(char op)
{
if(op=='*'||op=='/')
return 2;
else if(op=='^'||op=='r')
return 3;
else if(op=='+'||op=='-')
return 1;
else
return 4;
}
bool compare(char op1,char op2)///<=
{
if(opl(op1)<=opl(op2))
return 1;
else return 0;
}
double cacu(double num1,char op,double num2)///infact it is mun2(op)num1
{
switch(op)
{
case '+':
return num2+num1;
case '-':
return num2-num1;
case '*':
return num2*num1;
case '/':
if(num1==0)
{
cerr<<"Divided by 0 error!"<<endl;
exit(1);
}
else
return num2/num1;
case '^':
return pow(num2,num1);
case 'r':
return pow(num1,1/num2);
#if DEBUG
default:
cerr<<"Unexpected operator error!"<<endl;
exit(1);
#endif
}
}
double caculate(const char* formula)
{
stack<double> numbers;
stack<char> operate;
double carry=0;
int afterpoint=0;
bool ap=false;
bool minus=false;
for(int a=0; formula[a]!='\0'; a++)
{
if(a==0&&formula[a]=='-')
minus=true;
else if(formula[a]=='.'&&ap)
{
cerr<<"No more than a decimal point!"<<endl;
exit(1);
}
else if(formula[a]=='.'&&!ap)
ap=true;
else if(formula[a]>='0'&&formula[a]<='9')
{
if(!ap)
{
carry*=10;
carry+=formula[a]-'0';
}
else
{
carry+=(formula[a]-'0')*pow(10,--afterpoint);
}
if((formula[a+1]<'0'||formula[a+1]>'9')&&formula[a+1]!='.')
{
if(minus)
{
carry=-carry;
minus=false;
}
numbers<<carry;
#if DEBUG
cerr<<"number"<<carry<<"in"<<endl;
#endif
carry=0;
afterpoint=0;
ap=false;
}
}
else if(formula[a]=='+'||formula[a]=='-'||formula[a]=='*'||formula[a]=='/'||formula[a]=='('||formula[a]=='^'||formula[a]=='r')
{
if(formula[a]=='-'&&(formula[a-1]=='+'||formula[a-1]=='-'||formula[a-1]=='*'||formula[a-1]=='/'||formula[a-1]=='('))
{
minus=!minus;
continue;
}
if(formula[a]=='+'&&(formula[a-1]=='+'||formula[a-1]=='-'||formula[a-1]=='*'||formula[a-1]=='/'||formula[a-1]=='('))
continue;
if(formula[a]=='r'&&(numbers.isempty()||formula[a-1]<'0'||formula[a-1]>'9'))
numbers<<2;
if(formula[a]=='('&&formula[a-1]==')')
operate<<'*';
if(operate.gettop()!='('&&!operate.isempty()&&compare(formula[a],operate.gettop()))
{
double num1=numbers.pop();
#if DEBUG
cerr<<num1<<"poped"<<endl;
#endif
double num2=numbers.pop();
#if DEBUG
cerr<<num2<<"poped"<<endl;
#endif
double ls=cacu(num1,operate.pop(),num2);
numbers<<ls;
#if DEBUG
cerr<<ls<<"in"<<endl;
#endif
}
operate<<formula[a];
#if DEBUG
cerr<<formula[a]<<"in"<<endl;
#endif
}
else if(formula[a]==')')
{
if(formula[a-1]=='(')
{
cerr<<'\a'<<"Meaningless Expression \"()\"!"<<endl;
exit(1);
}
while(operate.gettop()!='(')
{
double num1=numbers.pop();
double num2=numbers.pop();
double ls=cacu(num1,operate.pop(),num2);
numbers<<ls;
}
operate.pop();
#if DEBUG
cerr<<"()compared"<<endl;
#endif
}
else
{
cerr<<'\a'<<"Illegal operator!"<<endl;
exit(1);
}
}
while(!operate.isempty())
{
double num1=numbers.pop();
double num2=numbers.pop();
double ls=cacu(num1,operate.pop(),num2);
numbers<<ls;
}
return numbers.pop();
}
#endif // CACULATOR_H
[/code]
stack是一个防溢出的栈
请高手们看看有没有错&能不能简化
功能上的建议也可以提

caculator.zip

102.63 KB, 下载次数: 24

exe文件

沙发
 楼主| 发表于 2013-11-10 16:14:32 | 只看该作者
注意是直接打表达式
板凳
发表于 2013-11-10 17:23:36 | 只看该作者
没太仔细看,两点建议,
第一, r是reminder吗? reminder一般和乘除是同级别的运算
第二,个人感觉词法分析分离出一个函数比较好

另外,应该提醒一下这是cpp,以及没有你的mylib.h是编译不了的,不然有人会直接拿去编译然后说编译不了
地板
发表于 2013-11-12 15:38:52 | 只看该作者
如果能给大家带来好处也不错。












英雄合击传奇
5#
 楼主| 发表于 2013-11-17 13:18:33 | 只看该作者
本帖最后由 981013 于 2013-11-17 13:21 编辑
rosynirvana 发表于 2013-11-10 17:23
没太仔细看,两点建议,
第一, r是reminder吗? reminder一般和乘除是同级别的运算
第二,个人感觉词法分 ...

的确是C++
r是开根号(3r2=1.2599210498949......)
"mylib.h"中有关代码:
[code=Cpp width=740px]template <typename T>
class Stack
{
public:
Stack():m_Data(NULL),m_nSize(0) {}
~Stack()
{
delete [] m_Data;
}
void push(const T Data)
{
if(m_Data==NULL)
{
m_nSize=1;
m_Data=new T[1];
m_Data[0]=Data;
return;
}
T* temp=m_Data;
m_nSize++;
m_Data=new T[m_nSize];
for(int a=1; a<m_nSize; a++)
m_Data[a]=temp[a-1];
m_Data[0]=Data;
delete [] temp;
}
void push(T* Data,int Size,bool way=true)
{
Size--;
for(int a=Size; a>=0; a--)
{
if(way)push(Data[a]);
else push(Data[Size-a]);
}
}
T pop()
{
if(m_nSize==0)
{
cerr<<"error:The stack is empty!"<<endl;
exit(1);
}
T* temp=m_Data;
m_nSize--;
m_Data=new T[m_nSize];
for(int a=1; a<=m_nSize; a++)
m_Data[a-1]=temp[a];
T ret=temp[0];
delete [] temp;
return ret;
}
void pop(T& Data)
{
Data=pop();
}
void pop(T* Data,int Size,bool way=true)
{
Size--;
for(int a=Size; a>=0; a--)
{
if(way)pop(Data[a]);
else pop(Data[Size-a]);
}
}
Stack& operator<<(const T Data)
{
push(Data);
return *this;
}
Stack& operator >>(T& Data)
{
Data=pop();
return *this;
}
bool isempty()
{
if(m_Data==NULL||m_nSize==0)
return true;
return false;
}
T gettop()
{
if(!isempty())return m_Data[0];
else return (T)0;
}
private:
T* m_Data;
int m_nSize;
};
[/code]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

广播台
特别关注
快速回复 返回顶部 返回列表