TXT四则运算计算器

时间:2023-03-10 01:47:03
TXT四则运算计算器

基本思想:使用getline函数从TXT文件中依次读出中缀表达式,将其转为后缀表达式后计算结果,并与用户结果比对。

整数、分数、小数的处理:将小数和整数都视为默认分母为1的分数.建立分数类,在中缀转换成后缀时将整数和小数转换为分数.

class Fenshu
{
private:
int fz;
int fm;
public:
int getfz(){
return fz;
}
int getfm(){
return fm;
}
void setfz(int FZ){
fz=FZ;
}
void setfm(int FM){
if(FM!=)
fm=FM;
else
cout<<"分母不能为0\n";
}
Fenshu(){
fz=-;
fm=-;
}
Fenshu(int a,int b){
fz=a;
if(b!=)
fm=b;
else cout<<"分母不能为0\n";
} int gcd(int a, int b)//求最大公约数
{
if(b == )
return a;
return gcd(b, a % b);
} void yuefen(){//约分
int Gcd=;
Gcd=gcd(fz,fm);
//cout<<"GCD:"<<Gcd<<endl;
fz=fz/Gcd;
fm=fm/Gcd;
// cout<<"results:";show();//test
} Fenshu operator+(Fenshu F)
{
return Fenshu(fz*F.fm+F.fz*fm,fm*F.fm);
}
Fenshu operator-(Fenshu F)
{
return Fenshu(fz*F.fm-F.fz*fm,fm*F.fm);
}
Fenshu operator*(Fenshu F)
{
return Fenshu(fz*F.fz,fm*F.fm);
}
Fenshu operator/(Fenshu F)
{
return Fenshu(fz*F.fm,fm*F.fz);
}
void show(){
cout<<fz<<"/"<<fm<<endl;
}
};

关于求最大公约数所使用的辗转相除法在上一篇博文中已经写过。为了之后代码书写方便,使用了重载。

中缀转换成后缀的处理:使用栈作为数据结构.

template <class ElemType> class MyStack
{
public:
const static int MAXSIZE =;
ElemType data[MAXSIZE];
int top;//栈顶脚标 public:
void init(); // 初始化栈
bool empty(); // 判断栈是否为空
ElemType gettop(); // 读取栈顶元素(不出)
void push(ElemType x); // 进栈
ElemType pop(); // 出栈
};

遇到的问题:

1.分数类定义是分子和分母作为int型变量,题目中出现的小数不能运算;

分析:要将小数转换成可存进分数的整数,小数点后每有一位,分子分母同乘10,

// 将数字字符串转变成相应的数字
Fenshu read_number(char str[],int *i)
{
Fenshu x(,);
int k = ;
while(str[*i] >='' && str[*i]<='') // 处理整数部分
{
x.setfz(x.getfz()*+(str[*i]-'') );
(*i)++;
} if(str[*i]=='.') // 处理小数部分
{
(*i)++;
while(str[*i] >= ''&&str[*i] <='')
{
x.setfz(x.getfz()*+(str[*i]-''));
x.setfm(x.getfm()*);
(*i)++;
k++;
}
}
return x;
}

2.对于存在负号'-'的题目提示栈为空;

分析:负号与减号的字符同为'-',导致在中缀转后缀时负号与减号进行了相同的操作(弹出两个栈顶的操作数)导致操作数错误操作;

解决方法:找出作为负号使用的'-',转换时替换成别的符号写入后缀表达式.计算后缀表达式时,将该符号后的数字作为0的减数压入栈

//修正负号的场合
if (pre[i]=='-') // 负号使用场合
{
if(pre[i-]<'' || pre[i-]>'' || pre[i-]=='(' || i==)
{
post[j++]='_';
i++;
continue;
}
}