顺序栈的实现
#include <iostream>
#include <cstdlib>
using namespace std;
const int STACK_INIT_SIZE = 20;
const int ERROR = 0;
const int OK = 1;
const int EMPTY = 0;
typedef int Status;
template <class T>
class SqStack
{
public:
SqStack();
~SqStack();
Status Push(T e);
Status Pop(T &e);
Status GetTop(T &e) const;
int StackLength() const;
Status IsEmpty();
void DispStack();
private:
T * base;
T *top; //栈顶指针
int stacksize;
};
//初始化一个栈
template <class T>
SqStack<T>::SqStack()
{
base = new T[STACK_INIT_SIZE];
top = base;
stacksize = STACK_INIT_SIZE;
}
//释放一个栈
template <class T>
SqStack<T>::~SqStack()
{
delete[] base;
}
//取顺序栈栈顶元素算法
template <class T>
Status SqStack<T>::GetTop(T &e) const
{
if (top == base)
{
return ERROR;
}
e = *(top - 1);
return OK;
}
//顺序栈入栈
template <class T>
Status SqStack<T>::Push(T e)
{
if (top - base >= stacksize)
{
return ERROR;
}
*top++ = e; //先赋值,再加指针
return OK;
}
//顺序栈出栈
template <class T>
Status SqStack<T>::Pop(T &e)
{
if (top == base)
{
return ERROR;
}
e = *--top; //先减指针,再取值
return OK;
}
//求栈长
template <class T>
int SqStack<T>::StackLength() const
{
int sizeCount = 0;
T *p = top - 1;
while (p >= base)
{
sizeCount++;
p--;
}
return sizeCount;
}
template <class T>
Status SqStack<T>::IsEmpty() //空栈为0,非空栈为1;
{
if (top == base)
{
return EMPTY;
}
else
{
return OK;
}
}
template <class T>
void SqStack<T>::DispStack()
{
T *p = top - 1;
while (p >= base)
{
cout << *p << " ";
p--;
}
cout << endl;
}
bool In(char c)
{
if (c>48 && c<57)
{
return false;
}
else
{
return true;
}
}
//判断优先级
char Precede(char o1, char o2)
{
char f = ' ';
switch (o2)
{
case '+':
case '-':
if (o1 == '(' || o1 == '#') //栈中符号优先级低
{
f = '<';
}
else
{
f = '>';
}
break;
case '*':
case '/':
if (o1 == '*' || o1 == '/' || o1 == ')')
{
f = '>';
}
else
{
f = '<';
}
break;
case '(':
if (o1 == ')')
{
cout << "括号匹配错误!" << endl;
exit(ERROR);
}
else
{
f = '<';
}
break;
case ')':
switch (o1)
{
case '(':
f = '='; //括号匹配
break;
case '#':
cout << "输入了错误的括号!~" << endl;
exit(ERROR);
default:
f = '>'; //其他情况站定元素的优先级更大
}
break;
case '#':
switch (o1)
{
case '#':
f = '=';
break;
case '(':
cout << "表达式中有多余的括号!!" << endl;
exit(ERROR);
default:
f = '>';
}
}
return f;
}
//运算函数
int Operate(int a, char theta, int b)
{
switch (theta)
{
case '+':
return a + b;
break;
case '-':
return a - b;
break;
case '*':
return a * b;
break;
case '/':
return a / b;
break;
}
return 0;
}
int EvalExpr(char *ptr)
{
SqStack<char> OPTR; //操作符栈
OPTR.Push('#'); //表达式起始符为'#'
SqStack<int> OPND; //操作数栈
char op, c, theta = ' ', x, m;
int a = 0; //操作数a
int b = 0; //操作数b
c = *ptr++; //每一个数当做字符取出,ptr遍历后移
OPTR.GetTop(op);
while (c != '#' || op != '#')
{
if (!In(c)) //如果是数字直接进栈
{
m = atoi(&c); //将字符转化为数字
OPND.Push(m); //数字入栈
c = *ptr++; //指针后移
}
else //如果是符号的话,则先将这个符号与栈顶符号进行比较
{
switch (Precede(op, c))
{
case '<': //栈中符号优先级低,继续进栈
OPTR.Push(c);
c = *ptr++;
break;
case '=': //优先级相等时,说明遇到括号,需要托括号
OPTR.Pop(x); //脱括号
c = *ptr++;
break;
case '>': //栈中符号优先级高时,先计算,再将结果压入栈中
OPTR.Pop(theta); //运算符
OPND.Pop(b); //操作数
OPND.Pop(a);
OPND.Push(Operate(a, theta, b)); //将新的运算结果插到栈中
break;
}
}
OPTR.GetTop(op); //每一次更新当前栈顶符号
}
OPND.GetTop(a); //计算结果
return a;
}
//将中缀式转化为后缀式
char *change(char *ptr)
{
char *result = new char;
int i = 0;
SqStack<char> OPTR;
OPTR.Push('#');
char e = ' ', op = ' ';
while (*ptr != '#')
{
if (!In(*ptr))
{
*(result + i++) = *ptr;
}
else
{
if (*ptr == '(') //左括号直接进栈
{
OPTR.Push(*ptr);
}
else if (*ptr == ')') //右括号出到左括号为止
{
do {
OPTR.Pop(e);
if (e != '(')
*(result + i++) = e; //将不为左括号的元素进栈
} while (e != '(');
}
else
{
OPTR.GetTop(op);
switch (Precede(op, *ptr))
{
case '<':
OPTR.Push(*ptr);
break;
case '=':
case '>':
do {
OPTR.Pop(e);
*(result + i++) = e;
OPTR.GetTop(op);
} while (Precede(op, *ptr) == '>'); //有可能出现多个优先的情况(+* -)
//+和*号必须都出去
OPTR.Push(*ptr);
}
}
}// end of else
ptr++;
}// end of while
while (OPTR.IsEmpty() != EMPTY)
{
OPTR.Pop(e);
if (e != '#')
*(result + i++) = e;
}
*(result + i) = '\0';
return result;
}
//后缀表达式求值
int EvalExpr_RPN(char *exp)
{
SqStack<int> s;
int a = 0, b = 0, e = 0;
while (*exp != '\0') //没有读取到字符串尾部
{
if (!In(*exp)) //读取的字符是数字不是符号
{
s.Push(*exp - 48); //字符转数字‘1’->1;数字直接入栈
}
else
{
s.Pop(b);
s.Pop(a);
s.Push(Operate(a, *exp, b)); //弹出两个数进行运算
}
exp++; //z指针后移
}
s.Pop(e); //计算结果为e
return e;
}
int main()
{
char a[17] = "1+2*(5-3)-6/2+4#";
char *exp = a;
int opnd = EvalExpr(exp);
cout<< "作为示例 " << exp << "的计算结果为 " << opnd <<endl;
cout << exp << "转化为后缀表达式为" << change(exp) <<endl;
cout << "后缀表达式求值为" << EvalExpr_RPN(change(exp)) <<endl;
char b[7] = "4+2*4#";
char *p = b;
cout<< p << change(p) <<endl;
cout<< EvalExpr_RPN(change(p)) << endl;
return 0;
}
#include <iostream>
using namespace std;
const int ERROR = 0;
const int OK = 1;
const int EMPTY = 1;
typedef int Status;
template <class T>
struct Node
{
T data;
Node<T> *next;
};
template <class T>
class LinkQueue
{
public:
LinkQueue();
~LinkQueue();
Status EnQueue(T e);
Status DeQueue(T &e);
int QueueLength();
Status IsEmpty();
void DispQueue();
Node<T>* getFront() const;
private:
Node<T> *front;
Node<T> *rear;
};
template <class T>
LinkQueue<T>::LinkQueue()
{
front = new Node<T>;
front->next = NULL;
rear = front;
}
template <class T>
LinkQueue<T>::~LinkQueue()
{
Node<T> *p = front;
while(p != rear)
{
p = p->next;
delete front;
front = p;
}
delete rear;
}
template <class T>
Status LinkQueue<T>::EnQueue(T e)
{
Node<T> *p = new Node<T>;
if(p == NULL)
{
return ERROR;
}
p->data = e;
p->next = NULL;
rear->next = p;
rear = p; //修改尾指针
return OK;
}
template <class T>
Status LinkQueue<T>::DeQueue(T &e)
{
Node<T> *p;
if(front == rear)
{
return ERROR;
}
p = front->next;
e = p->data;
front->next = p->next;
if(rear == p) //只有两个元素的情况,此时需要修改rear指针
{
rear = front;
}
delete p;
return OK;
}
template <class T>
int LinkQueue<T>::QueueLength()
{
int count = 0;
Node<T> *p = front;
while(p != rear)
{
++count;
p = p->next;
}
return count;
}
template <class T>
Status LinkQueue<T>::IsEmpty()
{
return (front == rear)?EMPTY:!EMPTY;
}
template <class T>
void LinkQueue<T>::DispQueue()
{
Node<T> *p = front->next;
while(p != NULL)
{
cout << p->data << " ";
p = p->next;
}
cout<<endl;
}
template <class T>
Node<T>* LinkQueue<T>::getFront() const
{
return front;
}
void SeeDoctor()
{
int select; //用户的选择
int flag = 1; //flag初始值为1,一旦下班->>退出系统,将其置为0,从而结束
int find;
int no; //病历号
LinkQueue<int> patientQueue;
Node<int> *p; //指向首元节点
while(flag == 1) //flag标识着何时退出
{
cout << "1:排队 2:就诊 3:查看排队 4:不再排队,余下依次就诊 5:下班 请选择 :";
cin>>select;
switch(select)
{
case 1:
cout << "请输入病历号:";
do
{
cin >> no; //需要判断病历号是否重复
find = 0; //find==1表示有重复的元素,需要重新添加
p = patientQueue.getFront()->next;
while(p != NULL && !find) //遍历查找
{
if(p->data == no)
{
find = 1;
}
else
{
p = p->next;
}
}
if(find)
{
cout<< "输入的病历号重复,请重新输入:";
}
}while(find == 1);//直到输入下一个不在队列中的结束循环
//直接进队
patientQueue.EnQueue(no);
break;
case 2:
if(patientQueue.IsEmpty()) //队空
{
cout << "没有排队的病人"<<endl;
}
else //队不空的条件
{
int temp;
patientQueue.DeQueue(temp);
cout << "病人" <<temp << "就诊"<<endl;
}
break;
case 3:
if(patientQueue.IsEmpty())
{
cout << "没有排队的病人。" <<endl;
}
else
{
cout<< "排队病人" ;
patientQueue.DispQueue();
}
break;
case 4:
if(patientQueue.getFront()->next == NULL)
{
cout << "没有排队的病人"<<endl;
}
else
{
cout << "病人按以下的顺序就诊:";
patientQueue.DispQueue();
}
flag = 0;
break;
case 5:
if(patientQueue.getFront()->next != NULL)
{
cout << "请排队的人明天就医。" <<endl;
}
flag = 0; //退出的条件
break;
//default:
}
}
}
int main()
{
SeeDoctor();
return 0;
}