简易计算器
输入一串包含 + - * / ()
的算式,给出计算结果的简单程序。
#include <cstring>
#include <iostream>
#define MAX_STACK 256
// 读取括号内的范围
int readBracket(char expr[], int &index)
{
// index 是初始括号 ( 的下一个索引
int level = 1; // 层级,表示括号的层数
while (level > 0)
{
char c = expr[index++];
switch (c)
{
case '(':
level++;
break;
case ')':
level--;
break;
}
}
// 最后 index 移动到括号 ) 后一位,因此 -1 就是 ) 的索引
return index - 1;
}
// 读取一个数
double getNum(char expr[], int &index)
{
double num = expr[index] - '0';
while (expr[++index] >= '0' && expr[index] <= '9')
{
num = num * 10 + expr[index] - '0';
}
return num;
}
// 计算指定范围内的表达式,其中 tmp 存放的是表达式最初的值
double calculate(char expr[], int left, int right, double res = 0, bool sign = false)
{
char c;
int index = left;
// 存放临时值
double tmp = 0;
while (index < right)
{
c = expr[index];
// 考虑变号
if (sign)
{
if (c == '+')
{
c = '-';
}
else if (c == '-')
{
c = '+';
}
}
switch (c)
{
// 遇到加减,直接返回两边相加的结果
case '+':
// 出现括号
if (expr[++index] == '(')
{
// 获取 ( 之后一位
int l = ++index;
int r = readBracket(expr, index);
// 括号中的值
tmp = calculate(expr, l, r);
}
// 上面表达式的值作为右边式子的初始值
res += calculate(expr, index, right, tmp);
return res;
case '-':
// 出现括号
if (expr[++index] == '(')
{
// 获取 ( 之后一位
int l = ++index;
int r = readBracket(expr, index);
// 括号中的值
tmp = calculate(expr, l, r);
}
// 上面表达式的值作为右边式子的初始值
// 进行减法递归时,右边部分的符号要发生变化,具体来说是与当前符号状态相反
res -= calculate(expr, index, right, tmp, !sign);
return res;
case '*':
// 出现括号
if (expr[++index] == '(')
{
// 获取 ( 之后一位
int l = ++index;
int r = readBracket(expr, index);
// 括号中的值
res *= calculate(expr, l, r);
}
else
{
res *= getNum(expr, index);
}
break;
case '/':
// 出现括号
if (expr[++index] == '(')
{
// 获取 ( 之后一位
int l = ++index;
int r = readBracket(expr, index);
// 括号中的值
res /= calculate(expr, l, r);
}
else
{
res /= getNum(expr, index);
}
break;
// 开头出现括号
case '(':
{
// 从下一个开始读取,获得括号最右边 ) 的位置
int l = ++index;
int r = readBracket(expr, index);
res += calculate(expr, l, r);
}
break;
default:
// 否则是在读第一个数
res += getNum(expr, index);
break;
}
}
return res;
}
void calculator()
{
char c;
char expr[MAX_STACK];
do
{
std::cout << "输入一个算式:" << std::endl;
int index = 0;
memset(expr, 0, MAX_STACK);
// 输入回车或超出限制就结束
while ((c = getchar()) != '\n' && index < MAX_STACK)
{
if (c == ' ')
{
continue;
}
expr[index] = c;
index++;
}
std::cout << "计算结果为:" << " = " << calculate(expr, 0, strlen(expr)) << std::endl
<< std::endl;
std::cout << "是否继续?y/n" << std::endl;
c = getchar();
// 用于存放回车
getchar();
std::cout << std::endl;
} while (c != 'n');
}
int main()
{
calculator();
return 0;
}