寒假无聊,编个计算器玩玩
我之前发过一次计算器的帖子,但是有bug所以我把bug修复后想再发一次(欢迎找bug)
写在前面:
- 使用Visual Studio 2022编写
- 支持加减乘除,可以套多个括号
- 我的思路是把表达式先转换成后缀表达式,再用栈进行运算(因为中缀表达式运算我不会编,百度了也看不懂QoQ)
参考:
代码(有点难看)
#include<iostream>
#include<stdio.h>
#include<stack>
#include<cmath>
using namespace std;
stack<double>a;
stack<char>b;
char c[10000];
char s[10000];
char z[10000];
int ss;
int cc;
double t1 = 0.0, t2 = 0.0;
bool pd1()
{
if ((!b.empty()) && (b.top() == '+' || b.top() == '-' || b.top() == '*' || b.top() == '/')) return 1;
else return 0;
}
bool pd2()
{
if ((!b.empty()) && (b.top() == '*' || b.top() == '/')) return 1;
else return 0;
}
void zq()
{
t2 = a.top();
a.pop();
t1 = a.top();
a.pop();
}
void sj()
{
c[cc] = b.top();
cc++;
b.pop();
}
void jf(int x)
{
if (pd1() == 1) while (pd1() == 1) sj();
if (x == 1) b.push('+');
else b.push('-');
ss++;
}
void cf(int x)
{
if (pd2() == 1) while (pd2() == 1) sj();
if (x == 1) b.push('*');
else b.push('/');
ss++;
}
void zh()
{
int t = strlen(s);
while (ss < t)
{
if ('0' <= s[ss] && '9' >= s[ss] || s[ss] == '.')
{
while ('0' <= s[ss] && '9' >= s[ss] || s[ss] == '.')
{
c[cc] = s[ss];
cc++;
ss++;
}
c[cc] = '@';
cc++;
}
else if (s[ss] == '+') jf(1);
else if (s[ss] == '-')
{
if (ss == 0 || ('0' > s[ss - 1] || '9' < s[ss - 1]) && s[ss - 1] != ')')
{
c[cc] = '~';
cc++;
ss++;
}
else jf(2);
}
else if (s[ss] == '*') cf(1);
else if (s[ss] == '/') cf(2);
else if (s[ss] == '(')
{
b.push('(');
ss++;
}
else if (s[ss] == ')')
{
while (b.top() != '(') sj();
b.pop();
ss++;
}
}
while (!b.empty()) sj();
}
void js()
{
int t = 0;
int tmp = 0;
int f = 0;
int f1 = 0;
double num1 = 0.0;
double num2 = 0.0;
while (t < cc)
{
if (('0' <= c[t] && '9' >= c[t]) || c[t] == '~')
{
num1 = 0.0;
num2 = 0.0;
f = 0;
tmp = 0;
if (c[t] == '~')
{
f1 = 1;
t++;
}
else
{
while (c[t] != '@')
{
if (f == 1)
{
num2 *= 10;
num2 += c[t] - '0';
tmp++;
}
if (c[t] == '.') f = 1;
if (f == 0)
{
num1 *= 10;
num1 += c[t] - '0';
}
t++;
}
a.push(num1 + num2 / pow(10, tmp));
if (f1 == 1)
{
a.top() *= -1;
f1 = 0;
}
}
}
if (c[t] == '@')t++;
else if (c[t] == '+')
{
zq();
a.push(t1 + t2);
t++;
}
else if (c[t] == '-')
{
zq();
a.push(t1 - t2);
t++;
}
else if (c[t] == '*')
{
zq();
a.push(t1 * t2);
t++;
}
else if (c[t] == '/')
{
zq();
a.push(t1 / t2);
t++;
}
}
}
void jz()
{
for (int i = 0; i < strlen(z); i++)
{
if (z[i] == '-' && z[i + 1] == '(')
{
s[ss] = '-';
ss++;
s[ss] = '1';
ss++;
s[ss] = '*';
ss++;
}
else
{
s[ss] = z[i];
ss++;
}
}
ss = 0;
}
int main()
{
char t = '@';
printf("计算器\n");
while (t == '@')
{
while (!a.empty()) a.pop();
while (!b.empty()) b.pop();
ss = 0;
cc = 0;
memset(s, '\0', sizeof(s));
memset(c, '\0', sizeof(c));
memset(z, '\0', sizeof(z));
printf("请输入\n");
cin >> z;
jz();
zh();
js();
printf("%.10lf\n按@键继续,其他键跳出\n", a.top());
cin >> t;
}
return 0;
}