编写算法,要求在键盘上输入一个算术表达式6+(7-1)*3+10/2, 输出表达式的值。
【分析】
表达式求值是栈的典型应用,计算机在求算术表达式的值分为两步:
(1)将中缀表达式转换为后缀表达式; (2) 依据后缀表达式计算表达式的值。
6+(7-1)*3+10/2的后缀表达式为671-3*+ 102/+,后缀表达式中不存在括号,并且操作数顺序保持不变,每输出两个操作数,输出一一个运算符,再进行运算。671-3*+ 102/ +的运算过程为:
(1)先输出7和1,然后计算7-1,得到6,后缀表达式为663*+ 102/+。
(2) 输出6和3,计算6*3,得到18, 后缀表达式为618+ 102/+。
(3)输出6和18,计算6+18,得到24,后缀表达式为24102/+。
(4)输出10和2,计算10/2, 得到5,后缀表达式为245+。
(5)输出24和5,计算24+5, 得到29。
code:
main.cpp
/*包含头文件*/
#include<stdio.h>
#include<string.h>
#include <iostream>
/*包含顺序栈基本操作实现函数*/
typedef char DataType;
#include"SeqStack.h"
#define MAXSIZE 50
/*操作数栈定义*/
typedef struct
{
float data[MAXSIZE];
int top;
}OpStack;
/*函数声明*/
void TranslateExpress(char s1[], char s2[]);
float ComputeExpress(char s[]);
void main()
{
char a[MAXSIZE], b[MAXSIZE];
float f;
printf("请输入一个算术表达式:\n");
gets_s(a);
printf("中缀表达式为:%s\n", a);
TranslateExpress(a, b);
printf("后缀表达式为:%s\n", b);
f = ComputeExpress(b);
printf("计算结果:%f\n", f);
system("pause");
}
float ComputeExpress(char a[])
/*计算后缀表达式的值*/
{
OpStack S; /*定义一个操作数栈*/
int i = 0, value;
float x1, x2;
float result;
S.top = -1; /*初始化栈*/
while (a[i] != '\0') /*依次扫描后缀表达式中的每个字符*/
{
if (a[i] != ' '&&a[i] >= '0'&&a[i] <= '9') /*如果当前字符是数字字符*/
{
value = 0;
while (a[i] != ' ') /*如果不是空格,说明数字字符是两位数以上的数字字符*/
{
value = 10 * value + a[i] - '0';
i++;
}
S.top++;
S.data[S.top] = value; /*处理之后将数字进栈*/
}
else /*如果当前字符是运算符*/
{
switch (a[i]) /*将栈中的数字出栈两次,然后用当前的运算符进行运算,再将结果入栈*/
{
case '+':
x1 = S.data[S.top];
S.top--;
x2 = S.data[S.top];
S.top--;
result = x1 + x2;
S.top++;
S.data[S.top] = result;
break;
case '-':
x1 = S.data[S.top];
S.top--;
x2 = S.data[S.top];
S.top--;
result = x2 - x1;
S.top++;
S.data[S.top] = result;
break;
case '*':
x1 = S.data[S.top];
S.top--;
x2 = S.data[S.top];
S.top--;
result = x1*x2;
S.top++;
S.data[S.top] = result;
break;
case '/':
x1 = S.data[S.top];
S.top--;
x2 = S.data[S.top];
S.top--;
result = x2 / x1;
S.top++;
S.data[S.top] = result;
break;
}
i++;
}
}
if (!S.top != -1) /*如果栈不空,将结果出栈,并返回*/
{
result = S.data[S.top];
S.top--;
if (S.top == -1)
return result;
else
{
printf("表达式错误");
exit(-1);
}
}
}
void TranslateExpress(char str[], char exp[])
/*把中缀表达式转换为后缀表达式*/
{
SeqStack S; /*定义一个栈,用于存放运算符*/
char ch;
DataType e;
int i = 0, j = 0;
InitStack(&S);
ch = str[i];
i++;
while (ch != '\0') /*依次扫描中缀表达式中的每个字符*/
{
switch (ch)
{
case'(': /*如果当前字符是左括号,则将其进栈*/
PushStack(&S, ch);
break;
case')': /*如果是右括号,将栈中的操作数出栈,并将其存入数组exp中*/
while (GetTop(S, &e) && e != '(')
{
PopStack(&S, &e);
exp[j] = e;
j++;
}
PopStack(&S, &e); /*将左括号出栈*/
break;
case'+':
case'-': /*如果遇到的是'+'和'-',因为其优先级低于栈顶运算符的优先级,所以先将栈顶字符出栈,并将其存入数组exp中,然后将当前运算符进栈*/
while (!StackEmpty(S) && GetTop(S, &e) && e != '(')
{
PopStack(&S, &e);
exp[j] = e;
j++;
}
PushStack(&S, ch); /*当前运算符进栈*/
break;
case'*': /*如果遇到的是'*'和'/',先将同级运算符出栈,并存入数组exp中,然后将当前的运算符进栈*/
case'/':
while (!StackEmpty(S) && GetTop(S, &e) && e == '/' || e == '*')
{
PopStack(&S, &e);
exp[j] = e;
j++;
}
PushStack(&S, ch); /*当前运算符进栈*/
break;
case' ': /*如果遇到空格,忽略*/
break;
default: /*如果遇到的是操作数,则将操作数直接送入数组exp中,并在其后添加一个空格,用来分隔数字字符*/
while (ch >= '0'&&ch <= '9')
{
exp[j] = ch;
j++;
ch = str[i];
i++;
}
i--;
exp[j] = ' ';
j++;
}
ch = str[i]; /*读入下一个字符,准备处理*/
i++;
}
while (!StackEmpty(S)) /*将栈中所有剩余的运算符出栈,送入数组exp中*/
{
PopStack(&S, &e);
exp[j] = e;
j++;
}
exp[j] = '\0';
}
SeqStack.h
#define STACKSIZE 100
typedef struct
{
DataType stack[STACKSIZE];
int top;
}SeqStack;
void InitStack(SeqStack *S)
/*将栈S初始化为空栈*/
{
S->top=0; /*把栈顶指针置为0*/
}
int StackEmpty(SeqStack S)
/*判断栈是否为空,栈为空返回1,否则返回0*/
{
if(S.top==0) /*当栈为空时*/
return 1; /*返回1*/
else /*否则*/
return 0; /*返回0*/
}
int GetTop(SeqStack S, DataType *e)
/*取栈顶元素。将栈顶元素值返回给e,并返回1表示成功;否则返回0表示失败。*/
{
if(S.top<=0) /*在取栈顶元素之前,判断栈是否为空*/
{
printf("栈已经空!\n");
return 0;
}
else
{
*e=S.stack[S.top-1]; /*取栈顶元素*/
return 1;
}
}
int PushStack(SeqStack *S,DataType e)
/*将元素e进栈,元素进栈成功返回1,否则返回0.*/
{
if(S->top>=STACKSIZE) /*在元素进栈前,判断是否栈已经满*/
{
printf("栈已满,不能进栈!\n");
return 0;
}
else
{
S->stack[S->top]=e; /*元素e进栈*/
S->top++; /*修改栈顶指针*/
return 1;
}
}
int PopStack(SeqStack *S,DataType *e)
/*出栈操作。将栈顶元素出栈,并将其赋值给e。出栈成功返回1,否则返回0*/
{
if(S->top==0) /*元素出栈之前,判断栈是否为空*/
{
printf("栈已经没有元素,不能出栈!\n");
return 0;
}
else
{
S->top--; /*先修改栈顶指针,即出栈*/
*e=S->stack[S->top]; /*将出栈元素赋值给e*/
return 1;
}
}
int StackLength(SeqStack S)
/*求栈的长度,即栈中元素个数,栈顶指针的值就等于栈中元素的个数*/
{
return S.top;
}
void ClearStack(SeqStack *S)
/*清空栈*/
{
S->top=0; /*将栈顶指针置为0*/
}
结果: