定义栈类
template<class T>
class arrayStack//自定义数组描述的栈类
{
public:
arrayStack(int init=100)//栈初始化
{
arrayLength = init;
arr = new T[arrayLength];
stackTop = -1;
}
~arrayStack() {delete[]arr;}
bool empty()const {return stackTop == -1;}
int size() {return stackTop + 1;}
T& top() {return arr[stackTop];}
//出栈
void pop() { arr[stackTop].~T(); stackTop--; }
//进栈
void push(const T& theElement)
{
if (stackTop == arrayLength - 1)//空间已满容量加倍
{
T* temp = new T[2 * arrayLength];
for (int i = 0; i <= stackTop; i++)
{
temp[i] = arr[i];
}
delete[]arr;
arr = temp;
delete[]temp;
arrayLength *= 2;
}
arr[++stackTop] = theElement;
}
private:
int arrayLength;//栈容量
int stackTop;//栈顶位置
T* arr;//栈的数组表示
};
计算器
对于一个有括号的加减乘除混合运算式字符串,对其的处理过程分为两步:
1.利用栈将中缀式化为后缀式,从而去除括号并且确定运算顺序。
2.利用栈计算后缀式。
中缀式->后缀式
string changeString(string& str)//中缀表达式转换为后缀表达式
{
string newStr = "";//后缀表达式
arrayStack<string> stack;//临时存放符号的栈
for (int i = 0; i < str.length(); i++)//遍历中缀式每个字符
{
string c = str.substr(i, 1);
if (c == "0" || c == "1" || c == "2" || c == "3" || c == "4" || c == "5" || c == "6" || c == "7" || c == "8" || c == "9")//数字:直接进入后缀式
{
newStr = newStr + c;
}
else if (c == "(")//左括号:直接进栈
{
stack.push(c);
}
else if (c == ")")//右括号:把左括号之前的所有符号全部出栈加进后缀式中,然后删除左括号
{
while (stack.top() != "(")
{
newStr = newStr + stack.top();
stack.pop();
}
stack.pop();
}
else if (c == "*" || c == "/")//乘除号:先让栈顶的乘除号出栈,然后自己进栈
{
while ((!stack.empty()) && (stack.top()=="*"|| stack.top() == "/"))
{
newStr = newStr + stack.top();
stack.pop();
}
stack.push(c);
}
else if (c == "+" || c == "-")//加减号:让左括号之前的所有符号出栈,然后自己进栈
{
while ((!stack.empty()) && stack.top() != "(")
{
newStr = newStr + stack.top();
stack.pop();
}
stack.push(c);
}
}
while (!stack.empty())//遍历完中缀式之后,让栈中剩余符号全部出栈
{
newStr = newStr + stack.top();
stack.pop();
}
return newStr;
}
计算后缀式
void calculate(string& str)//传入后缀式
{
arrayStack<double> stack;//用于临时存放数字
for (int i = 0; i < str.length(); i++)
{
string c = str.substr(i, 1);
if (c == "0" || c == "1" || c == "2" || c == "3" || c == "4" || c == "5" || c == "6" || c == "7" || c == "8" || c == "9")//数字:直接进栈
{
//利用流将字符串转为数字
stringstream ss(c);
double num;
ss >> num;
stack.push(num);
}
else if (c == "+" || c == "-" || c == "*" || c == "/")//符号:取出栈顶的两个数字进行运算,将运算结果压入栈中
{
double a = stack.top();
stack.pop();
double b = stack.top();
stack.pop();
if (c == "+")
{
b += a;
}
else if (c == "-")
{
b -= a;
}
else if (c == "*")
{
b *= a;
}
else if (c == "/")
{
if (a == 0)
{
cout << "除数不应为零!" << endl;
}
else
{
double c = (double)b / (double)a;
b = c;
}
}
stack.push(b);
}
}
//后缀式遍历完之后,栈顶数字即为运算结果
//由于涉及除法,于是决定将结果保留两位小数
printf("%0.2f\n", stack.top());
}