第一次写博客,心情有点小激动呢。本人小菜,学习完了c++,现在刚开始学习数据结构。前两天用c++实现了一个控制台计算器,想我菜鸟也是费了一番周折。计算器功能:支持整形和浮点型基本运算,支持括号。也支持负数,但是在算式中需要加上括号。
废话 不多说,上代码。大神勿喷!!不足之处,还望众大神多多提点。
创建一个Stack类
#ifndef STACK_H
#define STACK_H
#include <iostream>
using namespace std;
const int maxSize = 20;
template <typename T>
class Stack
{
public:
T nums[maxSize];
int count;
public:
Stack() //构造函数,并初始化栈
{
count = 0;
}
void initStack() //初始化栈函数
{
count = 0;
}
bool empty()
{
if (count == 0)
return true;
return false;
}
bool full()
{
if (count == maxSize)
return true;
return false;
}
T get_top(T &num)
{
if (empty()) //若栈为空报错
{
cout << "1underflow!" << endl;
return -1;
}
else
num = nums[count - 1];
return num;
}
void push(T num)
{
if (full())
{
cout << "overflow!" << endl;
}
else
{
nums[count] = num;
count++;
}
}
void pop()
{
if (empty())
{
cout << "2underflow!" << endl;
}
else
count--;
}
};
#endif
创建计算类
#include <cstring>
#include "Stack.h"
class Cal
{
public :
Stack<double> numStack;
Stack<char> charStack;
void getNum(char *str)
{
int len = strlen(str);
*(str + len) = '#'; //在字符串尾加上#,作为结束标志
charStack.push('#'); //压入#用于比较优先级
char sign = '\0'; //定义一个开关用于检验括号后的数字是否为负数
while (*str)
{
//遇到字符数字将其转化为数值型
if (isdigit(*str) || *str == '.')
{
double num = 0;
while (isdigit(*str))
{
num = num * 10 + (*(str++) - '0');
}
if (*(str) == '.')
{
str++;
double temp = 0.1;
while (isdigit(*str))
{
num = num + (*(str++) - '0') * temp;
temp /= 10;
}
}
//检查该数字是否是负数
char beforeOpe;
charStack.get_top(beforeOpe);
if (beforeOpe == '-')
{
if (numStack.empty())
{
numStack.push(-num);
charStack.pop();
}
else if(sign == '(') //解决括号里的负数
{
numStack.push(-num);
charStack.pop();
sign = '\0';
}
else
numStack.push(num);
}
else
{
numStack.push(num);
}
}
else if (*str == '(') //遇到左括号将其压入运算符栈
{
charStack.push(*str);
str++;
if (*str == '-')
sign = '(';
}
else if (*str == ')') //遇到又括号将前面算式弹出计算直到遇到左括号
{
char beforeOpe;
charStack.get_top(beforeOpe);
while (beforeOpe != '(')
{
double leftNum, rightNum;
numStack.get_top(rightNum);
numStack.pop();
numStack.get_top(leftNum);
numStack.pop();
cal(leftNum, rightNum, beforeOpe);
charStack.pop();
charStack.get_top(beforeOpe);
}
charStack.pop(); //弹出左括号
str++;
}
else
{
char beforeOpe;
charStack.get_top(beforeOpe);
if (getPri(*str) > getPri(beforeOpe)) //如果该优先级大于前面的压栈
{
charStack.push(*str);
str++;
}
else if ((getPri(*str) == 0) && getPri(beforeOpe) == 0) //当前后均为#时跳出循环,运算结束
{
break;
}
else //如果小于前面的,弹出运算
{
double leftNum, rightNum;
numStack.get_top(rightNum);
numStack.pop();
numStack.get_top(leftNum);
numStack.pop();
cal(leftNum, rightNum, beforeOpe);
charStack.pop();
}
}
}
}
void cal(double leftNum, double rightNum, char ch) //运算函数
{
switch (ch)
{
case '+':
numStack.push(leftNum + rightNum);
break;
case '-':
numStack.push(leftNum - rightNum);
break;
case '*':
numStack.push(leftNum * rightNum);
break;
case '/':
if (rightNum)
numStack.push(leftNum / rightNum);
else
cout << "除数不能为0!" << endl;
break;
default:
break;
}
}
int getPri(char ch) //获取运算符优先级
{
switch (ch)
{
case'#':
return 0;
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '(':
return -1;
}
}
void getResult()
{
double res;
if (numStack.empty())
{
cout << "请输入算式!" << endl;
}
else
{
numStack.get_top(res);
cout << "relult=" << res << endl << endl;
}
}
};
main 函数
#include "Cal.h"
int main()
{
Cal cal;
char str[30];
while (1)
{
cout << "请输入算式:" << endl;
cin >> str;
cal.getNum(str);
cal.getResult();
cal.numStack.initStack(); //清空数字栈,开始下次计算
cal.charStack.initStack(); //清空运算符栈
}
return 0;
}
好吧,以前没有弄过。没有搞出行号 =_=||。凑合看吧。。