使用的数据结构书本是 殷人昆 主编的,
为了熟悉课本的代码就边写边打边改
1.自己手写栈
#pragma once
#include<iostream>
using namespace std;
template<class T>
struct LinkedNode {
T x;
LinkedNode<T> *next;
};
template<class T>
class LinkedStack
{
public:
LinkedStack() :top(NULL) {}
~LinkedStack(){ makeEmpty(); };
void makeEmpty();
void push(T& x);
bool pop(T& x);
bool getTop(T& x)const;
bool IsEmpty()const { return(top == NULL) ? true : false; }
int getSize()const;
private:
LinkedNode<T>* top;
};
template<class T>
void LinkedStack<T>::makeEmpty() {
LinkedNode<T> *p;
while (top != NULL)
{
p = top;
top = top->next;
delete p;
}
};
template<class T>
void LinkedStack<T>::push(T& x)
{
LinkedNode<T>* temp = new LinkedNode<T>;
temp->x = x;
temp->next = top;
top = temp;
}
template<class T>
bool LinkedStack<T>::pop(T& x)
{
if (IsEmpty() == true)
return false;
LinkedNode<T>* temp = top;
top = top->next;
x = temp->x;
delete temp;
return true;
}
template<class T>
bool LinkedStack<T>::getTop(T& x)const
{
if (IsEmpty() == true)
return false;
x = top->x;
return true;
}
template<class T>
int LinkedStack<T>::getSize() const
{
int size = 0;
LinkedNode<T>* temp = top;
while (top != NUL)
{
top = top->next;
size++;
}
return size;
}
2.Calculator类
#pragma once
#include<math.h>
#include"stack.h"
#include<string>
#include<iostream>
using namespace std;
class Calculator {
public:
Calculator() {};
void Run(string str);
void Clear();
LinkedStack<double> s;
private:
void addOperand(double value);//进操作数栈队
bool get2Operands(double& left, double& right);//从栈中退出两个操作数
void DoOperator(char op);//形成运算指令,进行计算
};
void Calculator::DoOperator(char op) {
//取两个操作数,根据两个操作数,根据操作符op形成运算指令并计算
double left, right, value;
int result;
result = get2Operands(left, right);
if (result == true)
{
//如果取两个操作数成功,则计算并出栈
switch (op) {
case'+':value = left + right;
s.push(value);
break;//plus
case'-':value = left - right;
s.push(value);
break;//sub
case'*':value = left*right;
s.push(value);
break;
case'/':if (right == 0.0) {
cerr << "Divide by 0!" << endl;
Clear();
}else{ value = left / right; }
break;
}
}
else Clear();//取操作数出错,出栈
}
bool Calculator::get2Operands(double& left, double& right) {
//取出两个操作数
if(s.IsEmpty()==true)
{
cerr << "缺少右操作数" << endl;
return false;
}
s.pop(right);
if (s.IsEmpty() == true)
{
cerr << "缺少左操作数" << endl;
return false;
}
s.pop(left);
return true;
}
void Calculator::addOperand(double value) {
//将操作数的value进操作数栈
s.push(value);
}
void Calculator::Run(string str) {
char ch;
double newOperand;
int len = str.length();//
for (int i = 0; i < len; i++)
{
ch = str[i];
switch (ch) {
case '+':
case'-':
case'*':
case'/':
DoOperator(ch);
break;
default:
newOperand = (double)(ch-'0');
addOperand(newOperand);
}
}
};
void Calculator::Clear() {
s.makeEmpty();
}
3.main函数
// Chapter3_表达式.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include"stack.h"
#include"calculator.h"
#include<string>
#include<math.h>
using namespace std;
bool isDigit(char a)
{
if (a >= '0'&&a <= '9')return true;
return false;
}
/*
isp栈内优先数
*/
int isp(char ch)
{
switch (ch)
{
case '#':
return 0;
case '(':
return 1;
case '*':
case '/':
case '%':
return 5;
case '+':
case '-':
return 3;
case ')':
return 6;
default:
return -1;
}
}
/*
icp栈外优先数
*/
int icp(char ch)
{
switch (ch)
{
case '#':
return 0;
case '(':
return 6;
case '+':
case '-':
return 2;
case '*':
case '/':
case '%':
return 4;
case ')':
return 1;
default:
return -1;
}
}
string postfix(string str)
{//把中缀表达式s转换成后缀表达式,设定s中最后一个字符是#
//并且"#"一开始先放在栈底
LinkedStack<char> s;
char ch = '#', ch1, op;
string tempStr = "";
int len = str.length();
s.push(ch);
int index = 0;
ch = str[index];
//a + b*(c + d);
while (s.IsEmpty() == false)
{
if (isDigit(ch))
{
tempStr = tempStr + ch;
index++;
ch = str[index];
}
else {
s.getTop(ch1);//取栈顶操作符
if (isp(ch1) < icp(ch)) {
s.push(ch);
index++;
ch = str[index];
}
else if (isp(ch1) > icp(ch)) {
s.pop(op);
tempStr = tempStr + op;
}
else {
s.pop(op);
if (op == '(') {
index++;
ch = str[index];
}
}
}
}
return tempStr;
}
int main()
{
string temp;
while (cin >> temp)
{
cout << "请输入表达式:" << endl;
cout << " 并在末尾加个 '#'便于运算:" << endl;
cout << "中缀表达式->后缀表达式:"<<postfix(temp)<< endl;
cout << "后缀表达式比较好处理多项表达式的计算" << endl;
cout << "现在开始从后缀表达式计算结果" << endl;
Calculator c;
c.Run(postfix(temp));
double result;
c.s.pop(result);
cout << result << endl;
cout << endl;
}
return 0;
}
总结:
1.写的有点乱,急急忙忙的改完之后就发上来了,有纰漏请指出,不完善/注释不完整也是问题
只要是书上已经注释了,自己看得懂懒得发了,发这里是为了监督自己学习,确实发到了CSDN自己主动性也强了,很开心
2.会不断更新的,自己落下的多.