栈的作用——波兰表达式的运用,计算字符表达式
2022/8/7 23:26:22
本文主要是介绍栈的作用——波兰表达式的运用,计算字符表达式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
栈的作用——波兰表达式的运用,计算字符表达式
目录- 栈的作用——波兰表达式的运用,计算字符表达式
- 1 创建一个链栈
- (1)链栈的存储结构
- (2)打印
- (3)进栈
- (4)出栈
- 2 中缀表达式转换为后缀表达式
- 3 计算后缀表达式
1 创建一个链栈
需完成进栈,出栈,打印的操作。
(1)链栈的存储结构
#define SUCCESS 1 #define ERROR 0 #define MAXSIZE 5 typedef int ElemType; typedef int LIST_STATUS; typedef char ElemCharType; typedef struct _Node { ElemType Data; struct _Node *Next; }Node; typedef struct _LINK_STACK { Node * Top; int Count; }LINK_STACK;
(2)打印
LIST_STATUS PrintLinkStack(LINK_STACK * const LinkStack) { Node *TraStackNode; printf("PrintLinkStack start\n"); if (NULL == LinkStack) { return ERROR; } printf("LinkStack->Top = 0x%x\n", LinkStack->Top); printf("LinkStack->Count = %d\n", LinkStack->Count); TraStackNode = LinkStack->Top; while (TraStackNode != NULL) { printf("TraStackNode = 0x%x, TraStackNode->Data = %d\n", TraStackNode, TraStackNode->Data); TraStackNode = TraStackNode->Next; } printf("PrintLinkStack end\n\n"); return SUCCESS; }
(3)进栈
LIST_STATUS PushLinkStack(LINK_STACK *LinkStack, int PushData) { LINK_STACK *TraLinkStack = LinkStack; Node *PushNode; printf("PushLinkStack start\n"); if (NULL == LinkStack) { return ERROR; } PushNode = (Node *)malloc(sizeof(Node)); PushNode->Data = PushData; PushNode->Next = TraLinkStack->Top; TraLinkStack->Top = PushNode; TraLinkStack->Count++; printf("PushLinkStack end\n"); return SUCCESS; }
(4)出栈
LIST_STATUS PopLinkStack(LINK_STACK *LinkStack, int *PopData) { LINK_STACK *TraLinkStack = LinkStack; LINK_STACK *DeleteNode; printf("PopLinkStack start\n"); if (NULL == LinkStack || NULL == LinkStack->Top) { return ERROR; } *PopData = TraLinkStack->Top->Data; DeleteNode = TraLinkStack->Top; TraLinkStack->Top = TraLinkStack->Top->Next; TraLinkStack->Count--; free(DeleteNode); printf("PopLinkStack end\n"); return SUCCESS; }
2 中缀表达式转换为后缀表达式
(1)需求与算法
中缀表达式为:9+(3-1)*3+10/2
要转换成后缀表达式为:9 3 1 - 3 * + 10 2 / +
算法:
符号优先级:"* /" > " + -",“(”与“)”做特殊情况处理
(2)进栈
① 进栈原则:新元素优先级 > 栈顶元素优先级
② 当新元素为“(",进栈
③ 只进新元素
(3)出栈
① 出栈的原则:新元素优先级 <= 栈顶元素优先级
②当新元素为“)”时,将到栈里面“(”(包括)之前的符号全部出栈
① 当符号不为"()"时,满足出栈原则时,新元素不断与栈顶元素比,不断出栈,直到不满足出栈条件,或者遇到“(”时,将新元素入栈
② 最后栈里面的元素也要按顺序出栈
(3)其它注意的问题
①注意多位数的处理
②注意每个数之间要有空格隔开
代码:
bool IfPopValid(LINK_STACK * const LinkStack, char NewChar) { LINK_STACK *TraStackNode = LinkStack; printf("IfNewCharPriorityNotHigh start\n"); /*Empty LinkStack*/ if (TraStackNode->Top == NULL && TraStackNode->Count == 0) { return false; } if (NewChar == '(') { return false; } else if (NewChar == ')') { return true; } else if (NewChar == '+' || NewChar == '-') { return true; } else if (NewChar == '*' || NewChar == '/') { if (TraStackNode->Top->Data == '+' || TraStackNode->Top->Data == '-') { return false; } else if (TraStackNode->Top->Data == '*' || TraStackNode->Top->Data == '/') { return true; } } printf("IfNewCharPriorityNotHigh end\n\n"); } LIST_STATUS PushInfixExpression(LINK_STACK *LinkStack, char NewChar) { LINK_STACK *TraStackNode = LinkStack; Node *AddNode = (Node *)malloc(sizeof(Node)); LIST_STATUS Status; printf("PushInfixExpression start\n"); printf("In PushInfixExpression, NewChar = %c\n", NewChar); Status = PushLinkStack(LinkStack, NewChar); printf("PushInfixExpression end\n\n"); return Status; } LIST_STATUS PopInfixExpression(LINK_STACK *LinkStack, char NewChar, char *PostfixExpression, int *PostEIndex) { LINK_STACK *TraStackNode = LinkStack; int *PopData = (int)malloc(sizeof(int)); printf("PopInfixExpression start\n"); printf("PopData = 0x%x\n", PopData); printf("In PopInfixExpression, NewChar = %c\n", NewChar); printf("In PopInfixExpression, PostfixExpression = %s\n", PostfixExpression); PrintCharLinkStack(LinkStack); if (NewChar == ')') { while (TraStackNode->Top != NULL) { if (TraStackNode->Top->Data != '(') { PopLinkStack(TraStackNode, PopData); PostfixExpression[(*PostEIndex)++] = *PopData; PostfixExpression[(*PostEIndex)++] = ' '; }else if (TraStackNode->Top->Data == '(') { PopLinkStack(TraStackNode, PopData); break; } //TraStackNode->Top = TraStackNode->Top->Next; } } else if (NewChar == '+' || NewChar == '-') { while ((TraStackNode->Top != NULL) && (TraStackNode->Top->Data != '(')) { PopLinkStack(TraStackNode, PopData); PostfixExpression[(*PostEIndex)++] = *PopData; PostfixExpression[(*PostEIndex)++] = ' '; //TraStackNode->Top = TraStackNode->Top->Next; } PushLinkStack(LinkStack, NewChar); } else if (NewChar == '*' || NewChar == '/') { while ( (TraStackNode->Top != NULL) && (TraStackNode->Top->Data != '(') && ((TraStackNode->Top->Data == '*') || (TraStackNode->Top->Data == '/')) ) { PopLinkStack(TraStackNode, PopData); printf("*PopData = %c\n", *PopData); PostfixExpression[(*PostEIndex)++] = *PopData; PostfixExpression[(*PostEIndex)++] = ' '; //TraStackNode->Top = TraStackNode->Top->Next; } PushLinkStack(LinkStack, NewChar); } printf("In PopInfixExpression, PostfixExpression = %s\n", PostfixExpression); printf("PopData = 0x%x\n", PopData); free(PopData); PrintCharLinkStack(LinkStack); printf("PopInfixExpression end\n\n"); } /*RPN*/ void RPNString(void) { char InfixExpression[] = "9+(3-1)*3+10/2";//9 3 1 - 3 * + 10 2 / + //char InfixExpression[] = "9313102";//9313102 //char InfixExpression[] = "2+1*3+2/1";//2 1 3 * + 2 1 / + //char InfixExpression[] = "14*23/32";//14 23 * 32 / //char InfixExpression[] = "(2+1)";//2 1 + //char InfixExpression[] = "3+(2-1)";//3 2 1 - + //char InfixExpression[] = "3+(2-1)*4";//3 2 1 - 4 * + char *PostfixExpression = (char *)malloc(sizeof(char) * sizeof(InfixExpression) * 2); int PostEIndex = 0; int TraIndex = 0; int ResData; LINK_STACK *LinkStack = (LINK_STACK *)malloc(sizeof(LINK_STACK)); LinkStack->Top = NULL; LinkStack->Count = 0; LINK_STACK *TraStackNode = LinkStack; char *PopData = (char *)malloc(sizeof(char)); printf("InfixExpression = %s\n", InfixExpression); for (TraIndex = 0; TraIndex < strlen(InfixExpression); ++TraIndex) { printf("In RPNString, InfixExpression[%d] = %c\n", TraIndex, InfixExpression[TraIndex]); if (InfixExpression[TraIndex] >= '0' && InfixExpression[TraIndex] <= '9') { PostfixExpression[PostEIndex++] = InfixExpression[TraIndex]; /*long number*/ while ( (TraIndex + 1 < strlen(InfixExpression)) && ((InfixExpression[TraIndex + 1] >= '0' && InfixExpression[TraIndex + 1] <= '9')) ) { PostfixExpression[PostEIndex++] = InfixExpression[++TraIndex]; } PostfixExpression[PostEIndex++] = ' '; } else if (IfPopValid(LinkStack, InfixExpression[TraIndex]) == true) { PopInfixExpression(LinkStack, InfixExpression[TraIndex], PostfixExpression, &PostEIndex); } else if (IfPopValid(LinkStack, InfixExpression[TraIndex]) == false) { PushInfixExpression(LinkStack, InfixExpression[TraIndex]); } } printf("In RPNString, PostfixExpression = %s\n", PostfixExpression); /*Pop remain operator*/ printf("Pop remain operator\n"); while ((TraStackNode->Top != NULL) && (TraStackNode->Count != 0)) { if (TraStackNode->Top->Next == NULL) { PopLinkStack(LinkStack, PopData); PostfixExpression[PostEIndex++] = *PopData; } else { PopLinkStack(LinkStack, PopData); PostfixExpression[PostEIndex++] = *PopData; PostfixExpression[PostEIndex++] = ' '; } } PrintCharLinkStack(LinkStack); PostfixExpression[PostEIndex++] = '\0'; printf("In RPNString, PostfixExpression = %s\n\n", PostfixExpression); /*Operate PostfixExpression*/ ResData = OpPostfixFunc(PostfixExpression, strlen(PostfixExpression)); printf("In RPNString, ResData = %d\n", ResData); free(PostfixExpression); free(LinkStack);
3 计算后缀表达式
(1)需求与算法
后缀表达式:9 3 1 - 3 * + 10 2 / +
计算出结果:20
算法:
(2)遇到数字
将数进栈
(3)遇到符号
将栈的最上面两个元素出栈,第一个出栈的元素作为被操作数,第二个出栈的元素作为操作数,符号操作的结果进栈
(4)其它注意的问题
①注意多位数的处理
②注意每个数之间有空格隔开
代码:
int OpPopDataFunc(char Op, int Data1, int Data2) { int ResData; if (Op == '+') { ResData = Data2 + Data1; return ResData; } else if (Op == '-') { ResData = Data2 - Data1; return ResData; } else if (Op == '*') { ResData = Data2 * Data1; return ResData; } else if (Op == '/') { ResData = Data2 / Data1; return ResData; } } int OpPostfixFunc(char *PostfixExpressionInput, int PostfixExpressionInputSize) { //char PostfixExpression[] = "1 10 + 234 - 10 *"; //char PostfixExpression[] = "2 1 +"; //char PostfixExpression[] = "9 3 1 - 3 * + 10 2 / +"; char *PostfixExpression = PostfixExpressionInput; int Ret; int TraIndex = 0; LINK_STACK *LinkStack = (LINK_STACK *)malloc(sizeof(LINK_STACK)); LinkStack->Top = NULL; LinkStack->Count = 0; int PushData = 0; int *PopData1 = (int *)malloc(sizeof(int)); int *PopData2 = (int *)malloc(sizeof(int)); int *ResData1 = (int *)malloc(sizeof(int)); int ResData2 = 0; int OpData; printf("\nOpPostfixFunc start\n"); printf("In OpPostfixFunc, PostfixExpression = %s\n", PostfixExpression); printf("PostfixExpressionInputSize = %d\n", PostfixExpressionInputSize); for (TraIndex = 0; TraIndex < PostfixExpressionInputSize; ++TraIndex) { printf("PostfixExpression[%d] = %c\n", TraIndex, PostfixExpression[TraIndex]); if (PostfixExpression[TraIndex] == ' ') { continue; } else if (PostfixExpression[TraIndex] >= '0' && PostfixExpression[TraIndex] <= '9') { PushData = PostfixExpression[TraIndex] - 48; printf("PushData 01 = %d\n", PushData); /*Judge wheather PostfixExpression[TraIndex] is long number*/ while ((TraIndex + 1 < PostfixExpressionInputSize) && (PostfixExpression[TraIndex + 1] != ' ')) { printf("In while, PostfixExpression[%d] = %c\n", TraIndex + 1, PostfixExpression[TraIndex + 1]); PushData = PushData * 10 + (PostfixExpression[TraIndex + 1] - 48); ++TraIndex; printf("PushData 02 = %d\n", PushData); } /*Push should make PostfixExpression[TraIndex] int type */ PushLinkStack(LinkStack, PushData); PrintLinkStack(LinkStack); } else if (PostfixExpression[TraIndex] == '+' || PostfixExpression[TraIndex] == '-' || PostfixExpression[TraIndex] == '*' || PostfixExpression[TraIndex] == '/') { PopLinkStack(LinkStack, PopData1); PopLinkStack(LinkStack, PopData2); /* printf("*PopData1 = %d\n", *PopData1); printf("*PopData2 = %d\n", *PopData2); */ OpData = OpPopDataFunc(PostfixExpression[TraIndex], *PopData1, *PopData2); printf("OpData = %d\n", OpData); PushLinkStack(LinkStack, OpData); } } PrintLinkStack(LinkStack); if (LinkStack->Count == 1) { PopLinkStack(LinkStack, ResData1); printf("*ResData1 = %d\n", *ResData1); ResData2 = *ResData1; } free(LinkStack); free(ResData1); free(PopData1); free(PopData2); printf("In OpPostfixFunc, ResData2 = %d\n", ResData2); return ResData2; }
打印结果:
InfixExpression = 9+(3-1)*3+10/2
In RPNString, InfixExpression[0] = 9
In RPNString, InfixExpression[1] = +
IfNewCharPriorityNotHigh start
IfNewCharPriorityNotHigh start
PushInfixExpression start
In PushInfixExpression, NewChar = +
PushLinkStack start
PushLinkStack end
PushInfixExpression end
In RPNString, InfixExpression[2] = (
IfNewCharPriorityNotHigh start
IfNewCharPriorityNotHigh start
PushInfixExpression start
In PushInfixExpression, NewChar = (
PushLinkStack start
PushLinkStack end
PushInfixExpression end
In RPNString, InfixExpression[3] = 3
In RPNString, InfixExpression[4] = -
IfNewCharPriorityNotHigh start
PopInfixExpression start
PopData = 0xf15f00
In PopInfixExpression, NewChar = -
In PopInfixExpression, PostfixExpression = 9 3 屯屯屯屯屯屯屯屯屯屯屯屯屯?
PrintCharLinkStack start
LinkStack->Top = 0xf20338
LinkStack->Count = 2
TraStackNode = 0xf20338, TraStackNode->Data = (
TraStackNode = 0xf15ec8, TraStackNode->Data = +
PrintCharLinkStack end
PushLinkStack start
PushLinkStack end
In PopInfixExpression, PostfixExpression = 9 3 屯屯屯屯屯屯屯屯屯屯屯屯屯?
PopData = 0xf15f00
PrintCharLinkStack start
LinkStack->Top = 0xf20370
LinkStack->Count = 3
TraStackNode = 0xf20370, TraStackNode->Data = -
TraStackNode = 0xf20338, TraStackNode->Data = (
TraStackNode = 0xf15ec8, TraStackNode->Data = +
PrintCharLinkStack end
PopInfixExpression end
In RPNString, InfixExpression[5] = 1
In RPNString, InfixExpression[6] = )
IfNewCharPriorityNotHigh start
PopInfixExpression start
PopData = 0xf15f00
In PopInfixExpression, NewChar = )
In PopInfixExpression, PostfixExpression = 9 3 1 屯屯屯屯屯屯屯屯屯屯屯屯?
PrintCharLinkStack start
LinkStack->Top = 0xf20370
LinkStack->Count = 3
TraStackNode = 0xf20370, TraStackNode->Data = -
TraStackNode = 0xf20338, TraStackNode->Data = (
TraStackNode = 0xf15ec8, TraStackNode->Data = +
PrintCharLinkStack end
PopLinkStack start
PopLinkStack end
PopLinkStack start
PopLinkStack end
In PopInfixExpression, PostfixExpression = 9 3 1 - 屯屯屯屯屯屯屯屯屯屯屯?
PopData = 0xf15f00
PrintCharLinkStack start
LinkStack->Top = 0xf15ec8
LinkStack->Count = 1
TraStackNode = 0xf15ec8, TraStackNode->Data = +
PrintCharLinkStack end
PopInfixExpression end
In RPNString, InfixExpression[7] = *
IfNewCharPriorityNotHigh start
IfNewCharPriorityNotHigh start
PushInfixExpression start
In PushInfixExpression, NewChar = *
PushLinkStack start
PushLinkStack end
PushInfixExpression end
In RPNString, InfixExpression[8] = 3
In RPNString, InfixExpression[9] = +
IfNewCharPriorityNotHigh start
PopInfixExpression start
PopData = 0xf15f00
In PopInfixExpression, NewChar = +
In PopInfixExpression, PostfixExpression = 9 3 1 - 3 屯屯屯屯屯屯屯屯屯屯?
PrintCharLinkStack start
LinkStack->Top = 0xf20370
LinkStack->Count = 2
TraStackNode = 0xf20370, TraStackNode->Data = *
TraStackNode = 0xf15ec8, TraStackNode->Data = +
PrintCharLinkStack end
PopLinkStack start
PopLinkStack end
PopLinkStack start
PopLinkStack end
PushLinkStack start
PushLinkStack end
In PopInfixExpression, PostfixExpression = 9 3 1 - 3 * + 屯屯屯屯屯屯屯屯?
PopData = 0xf15f00
PrintCharLinkStack start
LinkStack->Top = 0xf15ec8
LinkStack->Count = 1
TraStackNode = 0xf15ec8, TraStackNode->Data = +
PrintCharLinkStack end
PopInfixExpression end
In RPNString, InfixExpression[10] = 1
In RPNString, InfixExpression[12] = /
IfNewCharPriorityNotHigh start
IfNewCharPriorityNotHigh start
PushInfixExpression start
In PushInfixExpression, NewChar = /
PushLinkStack start
PushLinkStack end
PushInfixExpression end
In RPNString, InfixExpression[13] = 2
In RPNString, PostfixExpression = 9 3 1 - 3 * + 10 2 屯屯屯屯屯妄
Pop remain operator
PopLinkStack start
PopLinkStack end
PopLinkStack start
PopLinkStack end
PrintCharLinkStack start
In RPNString, PostfixExpression = 9 3 1 - 3 * + 10 2 / +
OpPostfixFunc start
In OpPostfixFunc, PostfixExpression = 9 3 1 - 3 * + 10 2 / +
PostfixExpressionInputSize = 22
PostfixExpression[0] = 9
PushData 01 = 9
PushLinkStack start
PushLinkStack end
PrintLinkStack start
LinkStack->Top = 0xf20408
LinkStack->Count = 1
TraStackNode = 0xf20408, TraStackNode->Data = 9
PrintLinkStack end
PostfixExpression[1] =
PostfixExpression[2] = 3
PushData 01 = 3
PushLinkStack start
PushLinkStack end
PrintLinkStack start
LinkStack->Top = 0xf20440
LinkStack->Count = 2
TraStackNode = 0xf20440, TraStackNode->Data = 3
TraStackNode = 0xf20408, TraStackNode->Data = 9
PrintLinkStack end
PostfixExpression[3] =
PostfixExpression[4] = 1
PushData 01 = 1
PushLinkStack start
PushLinkStack end
PrintLinkStack start
LinkStack->Top = 0xf20478
LinkStack->Count = 3
TraStackNode = 0xf20478, TraStackNode->Data = 1
TraStackNode = 0xf20440, TraStackNode->Data = 3
TraStackNode = 0xf20408, TraStackNode->Data = 9
PrintLinkStack end
PostfixExpression[5] =
PostfixExpression[6] = -
PopLinkStack start
PopLinkStack end
PopLinkStack start
PopLinkStack end
OpData = 2
PushLinkStack start
PushLinkStack end
PostfixExpression[7] =
PostfixExpression[8] = 3
PushData 01 = 3
PushLinkStack start
PushLinkStack end
PrintLinkStack start
LinkStack->Top = 0xf20698
LinkStack->Count = 3
TraStackNode = 0xf20698, TraStackNode->Data = 3
TraStackNode = 0xf204d8, TraStackNode->Data = 2
TraStackNode = 0xf20408, TraStackNode->Data = 9
PrintLinkStack end
PostfixExpression[9] =
PostfixExpression[10] = *
PopLinkStack start
PopLinkStack end
PopLinkStack start
PopLinkStack end
OpData = 6
PushLinkStack start
PushLinkStack end
PostfixExpression[11] =
PostfixExpression[12] = +
PopLinkStack start
PopLinkStack end
PopLinkStack start
PopLinkStack end
OpData = 15
PushLinkStack start
PushLinkStack end
PostfixExpression[13] =
PostfixExpression[14] = 1
PushData 01 = 1
In while, PostfixExpression[15] = 0
PushData 02 = 10
PushLinkStack start
PushLinkStack end
PrintLinkStack start
LinkStack->Top = 0xf206d0
LinkStack->Count = 2
TraStackNode = 0xf206d0, TraStackNode->Data = 10
TraStackNode = 0xf207b0, TraStackNode->Data = 15
PrintLinkStack end
PostfixExpression[16] =
PostfixExpression[17] = 2
PushData 01 = 2
PushLinkStack start
PushLinkStack end
PrintLinkStack start
LinkStack->Top = 0xf20580
LinkStack->Count = 3
TraStackNode = 0xf20580, TraStackNode->Data = 2
TraStackNode = 0xf206d0, TraStackNode->Data = 10
TraStackNode = 0xf207b0, TraStackNode->Data = 15
PrintLinkStack end
PostfixExpression[18] =
PostfixExpression[19] = /
PopLinkStack start
PopLinkStack end
PopLinkStack start
PopLinkStack end
OpData = 5
PushLinkStack start
PushLinkStack end
PostfixExpression[20] =
PostfixExpression[21] = +
PopLinkStack start
PopLinkStack end
PopLinkStack start
PopLinkStack end
OpData = 20
PushLinkStack start
PushLinkStack end
PrintLinkStack start
LinkStack->Top = 0xf205f0
LinkStack->Count = 1
TraStackNode = 0xf205f0, TraStackNode->Data = 20
PrintLinkStack end
PopLinkStack start
PopLinkStack end
*ResData1 = 20
In OpPostfixFunc, ResData2 = 20
In RPNString, ResData = 20
这篇关于栈的作用——波兰表达式的运用,计算字符表达式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南