1 栈的顺序存储结构
通过线性表来实现
seqlist.h
#ifndef __MY_SEQLIST_H__
#define __MY_SEQLIST_H__
typedef void SeqList;
typedef void SeqListNode;
// 创建并且返回一个空的线性表
SeqList* SeqList_Create(int capacity);
// 销毁一个线性表list
void SeqList_Destory(SeqList* list);
// 将一个线性表list中的所有元素清空,线性表回到创建时的初始状态
void SeqList_Clear(SeqList* list);
// 返回一个线性表list中的元素个数
int SeqList_Length(SeqList* list);
int SeqList_Capacity(SeqList* list);
// 向一个线性表list的pos位置中插入新元素node
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos);
// 获取一个线性表list的pos位置处的元素
SeqListNode* SeqList_Get(SeqList* list, int pos);
// 删除一个线性表list的pos处元素,返回值为被删除的元素,NULL表示删除失败
SeqListNode* SeqList_Delete(SeqList* list, int pos);
#endif
seqstack.h
// seqstack.h
#ifndef _MY_SEQSTACK_H_
#define _MY_SEQSTACK_H_
#include"seqlist.h"
typedef void SeqStack;
SeqStack* SeqStack_Create(int capacity);
void SeqStack_Destory(SeqStack* stack);
void SeqStack_Clear(SeqStack* stack);
void SeqStack_Push(SeqStack* stack, void* item);
void* SeqStack_Pop(SeqStack* stack);
void* SeqStack_Top(SeqStack* stack);
int SeqStack_Size(SeqStack* stack);
int SeqStack_Capacity(SeqStack* stack);
#endif // !_MY_SEQSTACK_H_
seqlist.c
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include"seqlist.h"
//结构体套一级指针
typedef struct _tag_SeqList {
int length;
int capacity;
unsigned int** node; //int *node[] 指针数组
}TSeqList;
SeqList* SeqList_Create(int capacity) {
TSeqList* tmp = NULL;
tmp = (TSeqList*)malloc(sizeof(TSeqList));
if (tmp == NULL) {
printf("func SeqList_Create() error");
return NULL;
}
memset(tmp, 0, sizeof(TSeqList));
//根据capacity大小分配节点空间
tmp->node = (unsigned int**)malloc(sizeof(unsigned int*) * capacity);
if (tmp->node == NULL) {
printf("func SeqList_Create() tmp->node error ");
return NULL;
}
tmp->capacity = capacity;
tmp->length = 0;
return tmp;
}
// 销毁一个线性表list
void SeqList_Destory(SeqList* list) {
TSeqList* tlist = NULL;
if (list == NULL) {
return;
}
tlist = (TSeqList*)list;
if (tlist->node != NULL) {
free(tlist->node);
}
free(tlist);
}
// 将一个线性表list中的所有元素清空,线性表回到创建时的初始状态
void SeqList_Clear(SeqList* list) {
TSeqList* tlist = NULL;
if (list == NULL) {
return;
}
tlist = (TSeqList*)list;
tlist->length = 0;
}
// 返回一个线性表list中的元素个数
int SeqList_Length(SeqList* list) {
TSeqList* tlist = NULL;
if (list == NULL) {
return -1;
}
tlist = (TSeqList*)list;
return tlist->length;
}
int SeqList_Capacity(SeqList* list) {
TSeqList* tlist = NULL;
if (list == NULL) {
return -1;
}
tlist = (TSeqList*)list;
return tlist->capacity;
}
// 向一个线性表list的pos位置中插入新元素node
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos) {
int i = 0, ret = 0;
TSeqList* tlist = NULL;
if (list == NULL || node==NULL || pos < 0) {
ret = -1;
printf("SeqList_Insert() error : %d\n", ret);
return ret;
}
tlist = (TSeqList*)list;
//判断是不是链表空间满了
if (tlist->length == tlist->capacity) {
ret = -2;
printf("SeqList_Insert() tlist->length == tlist->capacity error : %d\n", ret);
return ret;
}
// 容错修正 长度为6,容量为20, 在pos=10插入,可以改为插入7位置
if (pos >= tlist->length) {
pos = tlist->length;
}
// 元素后移
for (i = tlist->length; i > pos; i--) {
tlist->node[i] = tlist->node[i-1];
}
// 元素插入
tlist->node[i] = node;
tlist->length++;
return 0;
}
// 获取一个线性表list的pos位置处的元素
SeqListNode* SeqList_Get(SeqList* list, int pos) {
int i = 0;
SeqListNode* ret = 0;
TSeqList* tlist = NULL;
if (list == NULL || pos < 0) {
printf("SeqList_Get() error : %d\n", ret);
return NULL;
}
tlist = (TSeqList*)list;
ret = (SeqListNode*)tlist->node[pos];
return ret;
}
// 删除一个线性表list的pos处元素,返回值为被删除的元素,NULL表示删除失败
SeqListNode* SeqList_Delete(SeqList* list, int pos) {
int i = 0;
SeqListNode* ret = 0;
TSeqList* tlist = NULL;
if (list == NULL || pos < 0) {
printf("SeqList_Delete() error : %d\n", ret);
return NULL;
}
tlist = (TSeqList*)list;
ret = (SeqListNode*)tlist->node[pos];
for (i = pos + 1; i < tlist->length; i++) {
tlist->node[i-1] = tlist->node[i];
}
tlist->length--;
return ret;
}
seqstack.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"seqstack.h"
#include"seqlist.h"
// 创建栈相当于创建线性表
SeqStack* SeqStack_Create(int capacity) {
return SeqList_Create(capacity);
}
// 销毁栈相当于销毁线性表
void SeqStack_Destory(SeqStack* stack) {
SeqList_Destory(stack);
}
// 清空栈相当于清空线性表
void SeqStack_Clear(SeqStack* stack) {
SeqList_Clear(stack);
}
// 压入栈 相当于链表尾部插入元素
void SeqStack_Push(SeqStack* stack, void* item) {
SeqList_Insert(stack, item, SeqStack_Size(stack)); // 尾插法
}
// 弹出栈 相当于取出链表尾部元素
void* SeqStack_Pop(SeqStack* stack) {
return SeqList_Delete(stack, SeqStack_Size(stack) - 1);
}
// 获取栈 相当于获取链表尾部元素
void* SeqStack_Top(SeqStack* stack) {
return SeqList_Get(stack, SeqStack_Size(stack) - 1);
}
// 获取栈的大小 相当于获取链表的实际长度
int SeqStack_Size(SeqStack* stack) {
return SeqList_Length(stack);
}
// 获取栈的容量 相当于获取链表的容量
int SeqStack_Capacity(SeqStack* stack) {
return SeqList_Capacity(stack);
}
源.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"seqstack.h"
#include"seqlist.h"
void main() {
int i = 0;
int a[10] = { 0 };
SeqStack* stack = NULL;
stack = SeqStack_Create(10);
if (stack == NULL) {
return;
}
// 遍历
for (i = 0; i < 5; i++) {
a[i] = i + 1;
SeqStack_Push(stack, &(a[i]));
}
printf("capacity:%d \n", SeqStack_Capacity(stack));
printf("length:%d \n", SeqStack_Size(stack));
printf("top:%d \n", *((int*)(SeqStack_Top(stack))));
while (SeqStack_Size(stack) > 0) {
int tmp = *((int*)SeqStack_Pop(stack));
printf("tmp:%d \t", tmp);
}
printf("\n");
}
结果
capacity:10
length:5
top:5
tmp:5 tmp:4 tmp:3 tmp:2 tmp:1
另一个例子
SqStack.h
#ifndef _SQSTACK_H
#define _SQSTACK_H
#define MAXSIZE 50
typedef struct _SQSTACK
{
int top; // 栈顶指针
unsigned int data[MAXSIZE];
}SqStack;
// 初始化,建立一个空栈S
void InitStack(SqStack *S);
// 将栈清空
void ClearStack(SqStack *S);
// 若栈为空则返回true,否则返回false
int StackEmpty(SqStack S);
// 若栈存在且非空,用e返回S的栈顶元素
void GetTop(SqStack S, void **e);
// 若栈S存在,插入新元素e到栈S中并成为其栈顶元素
void Push(SqStack *S, void *e);
// 删除栈S中的栈顶元素,并用e返回其值
void Pop(SqStack *S, void **e);
// 返回栈S的元素个数
int StackLength(SqStack S);
#endif // _SQSTACK_H
SqStack.c
#include "SqStack.h"
#include <string.h>
void InitStack(SqStack *S)
{
// 空栈
S->top = -1;
memset(S->data, 0, sizeof(S->data));
}
void ClearStack(SqStack *S)
{
S->top = -1;
}
int StackEmpty(SqStack S)
{
if (S.top == -1)
{
return 1;
}
return 0;
}
void GetTop(SqStack S, void **e)
{
// 栈为空
if (S.top == -1)
{
return;
}
*e = (void*)S.data[S.top];
}
void Push(SqStack *S, void *e)
{
// 栈已经满了
if (S->top == MAXSIZE - 1)
{
return;
}
// 栈顶上移
S->top++;
// 赋值
S->data[S->top] = (unsigned int)e;
}
void Pop(SqStack *S, void **e)
{
// 栈为空
if (S->top == -1)
{
return;
}
// 赋值
*e = S->data[S->top];
// 栈顶指针下移
S->top--;
}
int StackLength(SqStack S)
{
return S.top + 1;
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "SqStack.h"
typedef struct stu
{
int id;
int age;
}Student;
void main()
{
Student stu[10];
// 定义栈变量
SqStack st;
// 初始化栈
InitStack(&st);
// 压栈
for (int i = 0; i < 10; ++i)
{
stu[i].id = i;
stu[i].age = i + 20;
// 压栈
Push(&st, (void*)&stu[i]);
}
printf("stack size = %d\n", StackLength(st));
// 出栈
while (StackEmpty(st) != 1)
{
Student* p;
// 取栈顶元素
GetTop(st, (void**)&p);
printf("stack top elem id = %d, age=%d\n", p->id, p->age);
// 删除栈顶元素
Pop(&st, (void*)&p);
printf("Delete stack elem id = %d, age=%d\n", p->id, p->age);
}
system("pause");
}
结果
stack size = 10
stack top elem id = 9, age=29
Delete stack elem id = 9, age=29
stack top elem id = 8, age=28
Delete stack elem id = 8, age=28
stack top elem id = 7, age=27
Delete stack elem id = 7, age=27
stack top elem id = 6, age=26
Delete stack elem id = 6, age=26
stack top elem id = 5, age=25
Delete stack elem id = 5, age=25
stack top elem id = 4, age=24
Delete stack elem id = 4, age=24
stack top elem id = 3, age=23
Delete stack elem id = 3, age=23
stack top elem id = 2, age=22
Delete stack elem id = 2, age=22
stack top elem id = 1, age=21
Delete stack elem id = 1, age=21
stack top elem id = 0, age=20
Delete stack elem id = 0, age=20
2 栈的链式存储
链式存储时,对头部元素进行操作比较方便 用链表实现栈
linklist.h
#ifndef _MYLINKLIST_H_
#define _MYLINKLIST_H_
typedef void LinkList;
/*
typedef struct _tag_LinkListNode LinkListNode;
struct _tag_LinkListNode{
LinkListNode *next;
}
*/
typedef struct _tag_LinkListNode {
struct _tag_LinkListNode* next;
}LinkListNode;
LinkList* LinkList_Create();
void LinkList_Destory(LinkList* list);
void LinkList_Clear(LinkList* list);
int LinkList_Length(LinkList* list);
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);
LinkListNode* LinkList_Get(LinkList* list, int pos);
LinkListNode* LinkList_Delete(LinkList* list, int pos);
#endif
linkstack.h
#ifndef _MY_LINKSTACK_H_
#define _MY_LINKSTACK_H_
typedef void LinkStack;
LinkStack* LinkStack_Create();
void LinkStack_Destroy(LinkStack* stack);
void LinkStack_Clear(LinkStack* stack);
int LinkStack_Push(LinkStack* stack, void* item);
void* LinkStack_Pop(LinkStack* stack);
void* LinkStack_Top(LinkStack* stack);
int LinkStack_Size(LinkStack* stack);
#endif //_MY_LINKSTACK_H_
linklist.c
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include"linklist.h"
typedef struct _tag_LinkList {
LinkListNode head;
int length;
}TLinkList;
LinkList* LinkList_Create() {
TLinkList* ret = NULL;
ret = (TLinkList*)malloc(sizeof(TLinkList));
memset(ret, 0, sizeof(TLinkList));
ret->length = 0;
ret->head.next = NULL;
return ret;
}
void LinkList_Destory(LinkList* list) {
if (list != NULL) {
free(list);
list = NULL;
}
return;
}
// 让链表变为初始值
void LinkList_Clear(LinkList* list) {
TLinkList* tList = 0;
if (list == NULL) {
return;
}
tList = (TLinkList*)list;
tList->length = 0;
tList->head.next = NULL;
return;
}
int LinkList_Length(LinkList* list) {
TLinkList* tList = 0;
if (list == NULL) {
return;
}
tList = (TLinkList*)list;
return tList->length;
}
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos) {
int ret = 0, i = 0;
TLinkList* tList = NULL;
LinkListNode* current = NULL;
if (list == NULL || node == NULL || pos < 0) {
ret = -1;
printf("LinkList_Insert error %d\n",ret);
return ret;
}
tList = (TLinkList*)list;
current = &(tList->head);
for (i = 0; i < pos && current->next != NULL; i++) {
current = current->next;
}
// 1 node连接后续链表
node->next = current->next;
// 2 前面链表连接新的链表
current->next = node;
tList->length++;
return ret;
}
LinkListNode* LinkList_Get(LinkList* list, int pos) {
int i = 0;
TLinkList* tList = NULL;
LinkListNode* current = NULL;
if (list == NULL || pos < 0) {
printf("LinkList_Get error %d\n");
return NULL;
}
tList = (TLinkList*)list;
current = &(tList->head); //辅助指针变量指向链表头部
for (i = 0; i < pos && current->next != NULL; i++) {
current = current->next;
}
return current->next;
}
LinkListNode* LinkList_Delete(LinkList* list, int pos) {
int i = 0;
TLinkList* tList = NULL;
LinkListNode* current = NULL;
LinkListNode* ret = NULL;
if (list == NULL || pos < 0) {
printf("LinkList_Delete error \n");
return NULL;
}
tList = (TLinkList*)list;
current = &(tList->head);
for (i = 0; i < pos && current->next != NULL; i++) {
current = current->next;
}
// 缓存被删除节点
ret = current->next;
current->next = ret->next;
tList->length--;
return ret;
}
linkstack.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"linkstack.h"
#include"linklist.h"
// 链表业务节点
typedef struct Teacher {
LinkListNode node;
void* item; //栈业务节点
}Teacher;
// 链表业务节点
typedef struct _tag_LinkStackNode {
LinkListNode node;
void* item; //栈业务节点
}TLinkListNode;
// 创建栈 相当于创建表
LinkStack* LinkStack_Create() {
return LinkList_Create();
}
// 销毁栈相当于销毁线性表
void LinkStack_Destroy(LinkStack* stack) {
LinkStack_Clear(stack);
LinkList_Destory(stack);
}
// 清空栈相当于清空线性表 涉及到栈元素生命周期管理
// 所有入栈节点都是malloc,若要清空栈,把栈中元素弹出,并且释放节点
void LinkStack_Clear(LinkStack* stack) {
if (stack == NULL) {
return;
}
while (LinkStack_Size(stack) > 0) {
LinkStack_Pop(stack);
}
}
// 栈添加元素相当于线性表头部插入元素
// *item栈的业务节点转化为链表业务节点
int LinkStack_Push(LinkStack* stack, void* item) {
TLinkListNode* tmp = NULL;
int ret = 0;
tmp = (TLinkListNode*)malloc(sizeof(TLinkListNode));
if (tmp == NULL) {
return -1;
}
memset(tmp, 0, sizeof(TLinkListNode));
tmp->item = item;
ret = LinkList_Insert(stack, (LinkListNode*)tmp, 0);
if (ret != 0) {
printf("func LinkList_Insert error\n");
if (tmp != NULL) {
free(tmp);
}
return ret;
}
return 0;
}
// 从栈中弹出元素 相当于 从线性表的头部删除元素
// 把线性表 业务节点 转化成 栈的业务节点
void* LinkStack_Pop(LinkStack* stack) {
void* item = NULL; // 栈的业务节点
TLinkListNode* tmp = NULL;
tmp = (TLinkListNode*)LinkList_Delete(stack, 0);
if (tmp == NULL) {
return NULL;
}
item = tmp->item;
// 因为LinkList_Insert分配内存 所以LinkList_Delete释放内存
free(tmp);
return item;
}
// 获取栈顶元素相当于获取线性表的0号位置
void* LinkStack_Top(LinkStack* stack) {
TLinkListNode* tmp = NULL;
tmp = (TLinkListNode*)LinkList_Get(stack, 0);
if (tmp == NULL) {
return NULL;
}
return tmp->item;
}
// 求栈的大小相当于求线性表len
int LinkStack_Size(LinkStack* stack) {
return LinkList_Length(stack);
}
源.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"linkstack.h"
void main() {
int i = 0;
int a[10] = { 0 };
LinkStack* stack = NULL;
stack = LinkStack_Create();
if (stack == NULL) {
return;
}
// 添加元素
for (i = 0; i < 5; i++) {
a[i] = i + 1;
LinkStack_Push(stack, &a[i]);
}
// 获取栈的基本属性
printf("len:%d \n", LinkStack_Size(stack));
printf("top:%d \n", *((int*)(LinkStack_Top(stack))));
// 删除栈元素
while (LinkStack_Size(stack) > 0) {
int tmp = *((int*)LinkStack_Pop(stack));
printf("tmp=%d ", tmp);
}
// 销毁栈
LinkStack_Destroy(stack);
}
结果
len:5
top:5
tmp=5 tmp=4 tmp=3 tmp=2 tmp=1
3 栈的应用
案例1:就近匹配
需要上面的linkstack.h依赖文件
main.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"linkstack.h"
int isLeft(char c) {
int ret = 0;
switch (c) {
case'<':
case'(':
case'[':
case'{':
case'\'':
case'\"':
ret = 1;
break;
default:
ret = 0;
break;
}
return ret;
}
int isRight(char c) {
int ret = 0;
switch (c) {
case'>':
case')':
case']':
case'}':
case'\'':
case'\"':
ret = 1;
break;
default:
ret = 0;
break;
}
return ret;
}
int match(char left, char right) {
int ret = 0;
switch (left)
{
case'<':
ret = (right == '>');
break;
case'(':
ret = (right == ')');
break;
case'[':
ret = (right == ']');
break;
case'{':
ret = (right == '}');
break;
case'\'':
ret = (right == '\'');
break;
case'\"':
ret = (right == '\"');
break;
default:
ret = 0;
break;
}
}
int scanner(const char* code) {
LinkStack* stack = LinkStack_Create();
int ret = 0;
int i = 0;
while (code[i] != '\0') {
if (isLeft(code[i])) {
LinkStack_Push(stack, (void*)(code + i)); //&code[i]
}
if (isRight(code[i])) {
char* c = (char*)LinkStack_Pop(stack);
if ((c == NULL) || !match(*c, code[i])) {
printf("%c does not match!\n", code[i]);
ret = 0;
break;
}
}
i++;
}
if (LinkStack_Size(stack) == 0 && (code[i] == '\0')){
printf("Succeed!\n");
ret = 1;
}
else {
printf("Invalid code\n");
ret = 0;
}
LinkStack_Destroy(stack);
return ret;
}
void main() {
const char* code = "#include <stdio.h> int main() { int a[4][4]; int (*p)[4]; p = a[0]; return 0;}";
scanner(code);
}
案例2:中缀表达式和后缀表达式
中缀转后缀:
遍历中缀表达式中的数字和符号
对于数字:直接输出
对于符号:
左括号:进栈
运算符号:与栈顶符号进行优先级比较
若栈顶符号优先级低:此符合进栈 (默认栈顶若是左括号,左括号优先级最低)
若栈顶符号优先级不低:将栈顶符号弹出并输出,之后进栈
右括号:将栈顶符号弹出并输出,直到匹配左括号
遍历结束:将栈中的所有符号弹出并输出
中缀转后缀
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"linkstack.h"
int isNumber(char c) {
return('0' <= c) && (c <= '9');
}
int isOperator(char c) {
return(c == '+') || (c == '-') || (c == '*') || (c == '/');
}
int isLeft(char c) {
return(c == '(');
}
int isRight(char c) {
return(c == ')');
}
int priority(char c) {
int ret = 0;
if ((c == '+') || (c == '-')) {
ret = 1;
}
if ((c == '*') || (c == '/')) {
ret = 2;
}
return ret;
}
void output(char c) {
if (c != '\0') {
printf("%c", c);
}
}
void transform(const char* exp) {
int i = 0;
LinkStack* stack = LinkStack_Create();
while (exp[i] != '\0') {
if (isNumber(exp[i])) {
output(exp[i]);
}
else if (isOperator(exp[i])) {
while (priority(exp[i]) <= priority((char)(int)LinkStack_Top(stack))) {
output((char)(int)LinkStack_Pop(stack));
}
LinkStack_Push(stack,(void *)(int)exp[i]);
}
else if (isLeft(exp[i])) {
LinkStack_Push(stack, (void*)(int)exp[i]);
}
else if (isRight(exp[i])) {
// char c = '\0'
while (!isLeft((char)(int)LinkStack_Top(stack))) {
output((char)(int)LinkStack_Pop(stack));
}
LinkStack_Pop(stack);
}
else {
printf("Invalid expression!");
break;
}
i++;
}
while (LinkStack_Size(stack) > 0&&exp[i]=='\0') {
output((char)(int)LinkStack_Top(stack));
LinkStack_Pop(stack);
}
}
void main() {
transform("8+(3-1)*5");
}
结果
831-5*+
后缀转中缀
遍历后缀表达式中的数字和符号
对于数字:进栈
对于符号:
从栈中弹出右操作数
从栈中弹出左操作数
根据符号进行运算
将运算结果压入栈中
遍历结束:栈中的唯一数字为计算结果
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"linkstack.h"
int isNumber3(char c) {
return('0' <= c) && (c <= '9');
}
int isOperator3(char c) {
return(c == '+') || (c == '-') || (c == '*') || (c == '/');
}
int value(char c) {
return (c - '0');
}
int express(int left, int right, char op) {
int ret = 0;
switch (op) {
case'+':
ret = left + right;
break;
case'-':
ret = left - right;
break;
case'*':
ret = left * right;
break;
case'/':
ret = left / right;
break;
default:
break;
}
return ret;
}
int compute(const char* exp) {
LinkStack* stack = LinkStack_Create();
int ret = 0;
int i = 0;
while (exp[i] != '\0') {
if (isNumber3(exp[i])) {
LinkStack_Push(stack, (void*)value(exp[i]));
}
else if (isOperator3(exp[i])) {
int right = (int)LinkStack_Pop(stack);
int left = (int)LinkStack_Pop(stack);
int result = express(left, right, exp[i]);
LinkStack_Push(stack, (void*)result);
}
else {
printf("Invalid expression!");
break;
}
i++;
}
if (LinkStack_Size(stack) == 1 && (exp[i] == '\0')) {
ret = (int)LinkStack_Pop(stack);
}
else {
printf("Invaild expression!");
}
LinkStack_Destroy(stack);
return ret;
}
void main() {
printf("8+(3-1)*5 = %d\n", compute("831-5*+"));
}
结果
8+(3-1)*5 = 18
#include <iostream>
#include <stack>
using namespace std;
bool isNumber(char c)
{
return c >= '0' && c <= '9';
}
bool isLeft(char c)
{
return c == '(';
}
bool isRight(char c)
{
return c == ')';
}
bool isOperator(char c)
{
return c == '+' || c == '-' || c == '*' || c == '/';
}
int priority(char c)
{
int ret = 0;
switch (c)
{
case '+':
case '-':
ret = 1;
break;
case '*':
case '/':
ret = 2;
break;
default:
break;
}
return ret;
}
void Transform(const char* p)
{
// int i = 0;
// stack<char> st;
// while (p[i] != '\0')
// {
// // 数字
// if (isNumber(p[i]))
// {
// // 直接输出
// cout << p[i];
// }
// // 左括号
// else if (isLeft(p[i]))
// {
// // 进栈
// st.push(p[i]);
// }
// // 运算符
// else if (isOperator(p[i]))
// {
// // 优先级的比较
// while (!st.empty() && priority(st.top()) >= priority(p[i]))
// {
// // 输出
// cout << st.top();
// st.pop();
// }
// // 进栈
// st.push(p[i]);
// }
// // 右括号
// else if (isRight(p[i]))
// {
// // 如果不是左括号, 弹出并输出
// while (!isLeft(st.top()))
// {
// cout << st.top();
// st.pop();
// }
// // 弹出左括号
// st.pop();
// }
// i++;
// }
//
// while (!st.empty())
// {
// cout << st.top();
// st.pop();
// }
/*
中缀转后缀算法:
遍历中缀表达式中的数字和符号:
对于数字:直接输出
对于符号:
左括号:进栈
运算符号:与栈顶符号进行优先级比较
若栈顶符号优先级低:此符号进栈
(默认栈顶若是左括号,左括号优先级最低)
若栈顶符号优先级不低:将栈顶符号弹出并输出,之后进栈
右括号:将栈顶符号弹出并输出,直到匹配左括号
遍历结束:将栈中的所有符号弹出并输出
*/
int i = 0;
stack<char> st;
while (p[i] != '\0')
{
// 数字
if (isNumber(p[i]))
{
// 直接输出
cout << p[i];
}
// 左括号
else if (isLeft(p[i]))
{
// 进栈
st.push(p[i]);
}
// 运算符
else if (isOperator(p[i]))
{
// 优先级比较
// 当前字符优先级低, 直接进栈
// if (priority(st.top() < priority(p[i])))
// {
// // 直接进栈
// st.push(p[i]);
// }
// 若栈顶符号优先级不低
while (!st.empty() && priority(st.top()) >= priority(p[i]))
{
// 输出
cout << st.top();
// 弹出栈顶
st.pop();
}
// 当前字符进栈
st.push(p[i]);
}
else if (isRight(p[i]))
{
// 寻找左括号
while (!st.empty() && !isLeft(st.top()))
{
// 输出
cout << st.top();
// 弹出栈顶符号
st.pop();
}
if (!st.empty())
{
// 弹出左括号
st.pop();
}
}
i++;
}
// 遍历结束
if (p[i] == '\0')
{
// 遍历结束
while (!st.empty())
{
// 输出
cout << st.top();
// 弹出
st.pop();
}
}
else
{
cout << "遍历没有完成..." << endl;
}
}
// 后缀表达式的计算
/*
计算规则
遍历后缀表达式中的数字和符号
对于数字:进栈
对于符号:
从栈中弹出右操作数
从栈中弹出左操作数
根据符号进行运算
将运算结果压入栈中
遍历结束:栈中的唯一数字为计算结果
*/
int express(int left, int right, char op)
{
int ret = -1000000;
switch (op)
{
case '+':
ret = left + right;
break;
case '-':
ret = left - right;
break;
case '*':
ret = left * right;
break;
case '/':
ret = left / right;
break;
default:
break;
}
return ret;
}
int compute(const char* p)
{
int i = 0;
stack<int> st;
while (p[i] != '\0')
{
// 数字
if (isNumber(p[i]))
{
// 进栈
st.push(p[i]-'0');
}
else if (isOperator(p[i]))
{
// 右操作数
int right = st.top();
st.pop();
// 左操作数
int left = st.top();
st.pop();
// 计算
int res = express(left, right, p[i]);
// 结果压入栈中
st.push(res);
}
i++;
}
if (p[i] == '\0' && st.size() == 1)
{
return st.top();
}
else
{
return -100000;
}
}
void main()
{
Transform("8+(3-1)*5");
cout << endl;
cout << "计算结果: " << compute("831-5*+") << endl;
system("pause");
}