本题在求后缀表达式的结构体的基础上再加了一个int变量,和数字入栈的函数
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include<string.h>
//若取出的字符是操作数,则加入后缀表达式
//若取出的字符是运算符:
//a.若为’(’,入栈;
//b.若为’)’,则依次把栈中的运算符加入后缀表达式,直到出现’(’,然后从栈中删除’(’;
//c.若为除了括号之外的其他运算符,当其优先级高于栈顶的运算符时,直接入栈;
//否则从栈顶开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,直到遇到一个比它优先级低或遇到了一个左括号为止。
struct node
{
char num;//内容,存放操作符
int shuzi;//存放数字
struct node* next;//链式表,指向下一个结点
};
typedef struct node* PNODE;
struct stack//存放栈顶的结构体,即栈
{
PNODE top;
int size;//栈的大小
};
typedef struct stack* Stack;
//创建一个空栈
Stack createStack()
{
Stack stack;
stack = (Stack)malloc(sizeof(struct stack));
if (stack != NULL)
{
stack->top = NULL;
stack->size = 0;
}
else printf("Out of space!");
return stack;
}
//判断栈是否为空栈
int isEmptyStack(Stack stack)
{
return(stack->top == NULL);
}
//入栈操作(头插法)(入字符)
void pushStack(Stack stack, char x)
{
PNODE p;
p = (PNODE)malloc(sizeof(struct node));
if (p == NULL)
{
printf("Out of space!\n");
}
else {
p->num = x;
p->next = stack->top;
stack->top = p;
stack->size++;
}
}
//入栈操作(头插法)(入数字)
void pushshuziStack(Stack stack, int x)
{
PNODE p;
p = (PNODE)malloc(sizeof(struct node));
if (p == NULL)
{
printf("Out of space!\n");
}
else {
p->shuzi = x;
p->next = stack->top;
stack->top = p;
stack->size++;
}
}
//出栈操作
void popStack(Stack stack)
{
PNODE p;
if (isEmptyStack(stack))
{
printf("Empty Stack pop!\n");
}
else {
p = stack->top;
stack->top = stack->top->next;
free(p);
stack->size--;
}
}
//取栈顶元素
char top_num(Stack stack)
{
if (stack->top == NULL)
{
printf("Empty Stack!\n");
}
else {
return(stack->top->num);
}
}
/*
函数名:inToPost,本函数名和参数不能更改
函数功能:将中缀表达式转换为后缀表达式输出
函数参数:中缀表达式,放在字符数组中
返回值:返回放有后缀表达式的栈
*/
Stack inToPost(char* expression)
{
//在此处填写代码,完成中缀表达式转换为后缀表达式并输出
/********** Begin **********/
Stack houzhui, fuhao;
houzhui = createStack();
fuhao = createStack();
int len;
len = strlen(expression);//得到字符串的长度
char q = '#';
pushStack(fuhao, q);
for (int i = 0; i < len; i++)//遍历数组
{
char ch = expression[i];
//若取出的字符是操作数,则加入后缀表达式
if (ch >= '0' && ch <= '9')
{
if (expression[i + 1] >= '0' && expression[i + 1] <= '9' && i != len - 1)//如果后面一个也是操作数就不加空格,除非是最后一个数
{
pushStack(houzhui, ch);
}
else {
pushStack(houzhui, ch);
pushStack(houzhui, ' ');
}
}
//a.若为’(’,入符号栈;
else if (ch == '(')
{
pushStack(fuhao, ch);
}
//b.若为’)’,则依次把栈顶的运算符加入后缀表达式,直到出现’(’,然后从栈中删除’(’;
else if (ch == ')')
{
while (fuhao->top->num != '(')
{
char topch = fuhao->top->num;
popStack(fuhao);//出栈栈顶
pushStack(houzhui, topch);//入栈后缀
pushStack(houzhui, ' ');//空格入栈,表示间隔
}
popStack(fuhao);//在符号栈中删除(
}
//c.若为除了括号之外的其他运算符,当其优先级高于栈顶的运算符时,直接入栈;
//否则从栈顶开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,直到遇到一个比它优先级低或遇到了一个左括号为止。
//假如是+,-,那么栈顶遇到(,进符号栈,否则栈顶一直出栈进后缀栈
else if (ch == '+' || ch == '-')
{
while (fuhao->top->num != '(')
{
if (fuhao->top->num == '#')
{
break;
}
char topch = fuhao->top->num;
popStack(fuhao);//出符号栈栈顶
pushStack(houzhui, topch);//入栈后缀
pushStack(houzhui, ' ');
}
pushStack(fuhao, ch);//此时的符号进入符号栈
}
//如果是* /,如果栈顶为* /,栈顶就出栈进入后缀栈,如果是 其他就入符号栈
else if (ch == '*' || ch == '/')
{
while (fuhao->top->num == '*' || fuhao->top->num == '/')
{
char topch = fuhao->top->num;
popStack(fuhao);//出符号栈栈顶
pushStack(houzhui, topch);//入栈后缀
pushStack(houzhui, ' ');
}
pushStack(fuhao, ch);//此时的符号进入符号栈
}
}
//数组遍历完,将符号栈中所有东西存入后缀栈
while (fuhao->top->num != '#')
{
char topch = fuhao->top->num;
popStack(fuhao);//出符号栈栈顶
pushStack(houzhui, topch);//入栈后缀
pushStack(houzhui, ' ');
}
return houzhui;
/********** End **********/
}
//print函数用于输出后缀表达式,参数是 inToPost的返回值
void print(Stack s)
{
Stack result;
result = createStack();//由于栈输出是逆序的,所以再来一个栈变成正序
while (s->size != 0)
{
char topch = s->top->num;
pushStack(result, topch);
//printf("%c", topch);
popStack(s);
}
while (result->size != 0)
{
char topch = result->top->num;
printf("%c", topch);
popStack(result);
}
}
/*
第三关
函数名:calExp,本函数名和参数不能更改
函数功能:调用inToPost函数求解后缀表达式,并求解后缀表达式的值返回
函数参数:
返回值:无
*/
int calExp(char* express)
{
//在此处填写代码,完成表达式求值并输出
/********** Begin **********/
Stack s = inToPost(express);
Stack zhengxu;
zhengxu = createStack();//由于栈是逆序的,所以再来一个栈变成正序
while (s->size != 0)
{
char topch = s->top->num;
pushStack(zhengxu, topch);
//printf("%c", topch);
popStack(s);
}
//基本思路,利用后缀表达式,将后缀表达式压入栈,变成正序的。
//再来一个栈,然后再遍历后缀栈,如果是操作数就入栈,是运算符就栈顶出两次栈,第一个在右第二个在左,运算出的结果再次入栈
//具体操作:1.查看栈顶,是数字就存入str数组,遇到空格就利用atoi()将str变成int,再存入栈顶的数字里,如果遇到运算符,第一个在右第二个在左,运算出的结果再次入栈
Stack result;
result = createStack();
char str[10];
int i=0;
int k;
while (zhengxu->size > 0)
{
i = 0;
k = 0;
while (zhengxu->top->num != ' ')
{
if (zhengxu->top->num >= '0' && zhengxu->top->num <= '9')
{
str[i] = zhengxu->top->num;
popStack(zhengxu);
i++;
}
else if(zhengxu->top->num=='*')
{
k = result->top->shuzi * result->top->next->shuzi;//出栈两个,进栈一个
popStack(result);
popStack(result);
popStack(zhengxu);
}
else if (zhengxu->top->num == '+')
{
k = result->top->shuzi + result->top->next->shuzi;//出栈两个,进栈一个
popStack(result);
popStack(result);
popStack(zhengxu);
}
else if (zhengxu->top->num == '-')
{
k = result->top->next->shuzi - result->top->shuzi;//出栈两个,进栈一个
popStack(result);
popStack(result);
popStack(zhengxu);
}
else if (zhengxu->top->num == '/')
{
k = result->top->next->shuzi - result->top->shuzi;//出栈两个,进栈一个
popStack(result);
popStack(result);
popStack(zhengxu);
}
}
if (i != 0)
{
k = atoi(str);
while (i >= 0)
{
str[i] = 0;
i--;
}//清空字符串
pushshuziStack(result, k);
k = 0;
}
if (k != 0)
{
pushshuziStack(result, k);
popStack(zhengxu);
}
else {
popStack(zhengxu);
}
}
return result->top->shuzi;
/********** End **********/
}
int main(void)
{
char express[80];
gets_s(express);
printf("%d", calExp(express));
}