实验三 栈的实现及应用

本次实验旨在掌握栈的存储和实现,通过VC++进行算术表达式的求值。实验中,设计了一个程序,接收以'#'为结束符的四则运算表达式,如2*(3+4),并利用算符优先法计算结果。在实现过程中,遇到的主要问题是判断运算符优先级和栈的边界条件,确保正确出栈并完成运算。最终,程序能成功对表达式求值并输出结果。

一、实验实习目的及要求

运行结果

1.掌握栈的存储表示和实现
2.掌握栈的基本操作实现。
3.掌握栈在解决实际问题中的应用。


二、实验实习设备(环境)及要求(软硬件条件)

实验在计算机机房,应用软件VC++;


三、实验实习项目、内容与步骤

问题描述:设计一个程序,演示用算符优先法对算术表达式求值的过程。利用算符优先关系,实现对算术四则混合运算表达式的求值。
(1)输入的形式:表达式,例如2*(3+4)#
包含的运算符只能有’+’ 、’-’ 、’’ 、’/’ 、’(’、 ‘)’,“#”代表输入结束符;
(2)输出的形式:运算结果,例如2
(3+4)=14;
(3)程序所能达到的功能:对表达式求值并输出。


四、实验实习所得结果及分析

运行结果
分析:按照题目所提示的内容,每一段文字用代码表示出来。中间出现的一些问题:
当C优先级小于栈符号的优先级时,开始运算,运算容易出现差错,需要明确运算到哪一步结束。两个栈也需要提起设好空的条件,及“#”,不然出栈运算不知道哪里结束。然后是每出一个栈元素,都需要把栈的top指向栈的下一位。


五、实验实习结果分析和(或)源程序调试过程

#include<stdio.h>
#include<stdlib.h>
#define OK 10000
#define ERROR 10001
struct node
{
	int data;
	struct node *next;
};
typedef struct node Node;
 
struct stack
{
	Node *top;
	int count;
};
typedef struct stack Stack;
int InitStack(Stack *S)//栈初始化
{
	S->top = NULL;
	S->count = 0;
 
    return OK;
}
int EmptyStack(Stack *S)//判断栈是否还有元素,有返回OK
{
	return (S->count == 0) ? OK : ERROR;
}
 
int Push(Stack *S,int e)
{
    Node *p = (Node *)malloc(sizeof(Node));
    if(NULL == p)
    {
        return ERROR;
    }
    p->data = e;
    p->next = S->top;
    S->top = p;
    S->count++;
    
    return OK;
}
int GetTop(Stack *S)//返回栈s栈顶元素
{
    if(NULL == S->top)
    {
        return ERROR;
    }
 
    return (S->top->data);
}

int getIndex(char theta)//输出运算符号优先级
{
	int index = 0;
	    switch (theta)
	    {
	    case '+':
	        index = 0;
	        break;
	    case '-':
	        index = 1;
	        break;
	    case '*':
	        index = 2;
	        break;
	    case '/':
	        index = 3;
        break;
	    case '(':
        index = 4;
        break;
	    case ')':
	        index = 5;
        break;
	    case '#':
	        index = 6;
	    default:break;
	    }
	    return index;
}
int Pop(Stack *S)//出栈顶元素
{
	Node *p;
	int e;
	
	if(NULL == S->top)
	{
        return ERROR;
    }
    p = S->top;
    e = p->data;
    S->top = p->next;
    free(p);
    S->count--;
	return e;
}
char getPriority(char theta1, char theta2)   //获取theta1与theta2之间的优先级  
{  
	const char Priority[][7] =     //算符间的优先级关系  
	{  
		{ '>','>','<','<','<','>','>' },  
		{ '>','>','<','<','<','>','>' },  
		{ '>','>','>','>','<','>','>' },  
        { '>','>','>','>','<','>','>' },  
        { '<','<','<','<','<','=','0' },  
		{ '>','>','>','>','0','>','>' },  
		{ '<','<','<','<','<','0','=' },  
	};  	
	int index1 = getIndex(theta1);  
	int index2 = getIndex(theta2);  
	return Priority[index1][index2];  
} 
int main()
{
	Stack opnd, opter;
	char str[100] ={0};
	int i = 0,tmp = 0,j;
	if (InitStack(&opnd) !=OK || InitStack(&opter) !=OK)//初始化两个栈
	{
		printf("Init Failure!\n");
		exit(1);
	}
	printf("请输入运算\n");
	scanf("%s",str);
	while(str[i] !='\0' || EmptyStack(&opter) !=OK)
	{
		if (str[i] >= '0' && str[i] <='9')
		{
			tmp = tmp * 10 + str[i] - '0';//是数字的话,记录在tmp中
			i++;
			if (str[i] < '0' || str[i] >'9')
			{
				Push(&opnd,tmp);//把操作数插入opnd
				tmp = 0;
			}
		}
		else
		{
			if ((EmptyStack(&opter) ==OK) || (GetTop(&opter)=='(' && str[i] !=')')|| //进栈不运算
					(getIndex(str[i])>getIndex(GetTop(&opter))))//栈opter为空,或者是左括号,或者数组符号优先级小于栈顶则直接进栈
			{
				Push(&opter,str[i]);
				i++;
				continue;
			}
 
			if (GetTop(&opter)=='(' && str[i] ==')')  //出栈不运算
			{
				Pop(&opter);
				i++;
				continue;
			}
 
			if ((str[i]=='\0' && EmptyStack(&opter) !=OK) || (str[i]==')' && GetTop(&opter) !='(')||  //出栈运算
					(getIndex(str[i])<=getIndex(GetTop(&opter))))
			{
				switch(Pop(&opter))//运算
				{
					case '+':
						Push(&opnd,Pop(&opnd)+Pop(&opnd));
						break;
					case '-':
						j = Pop(&opnd);
						Push(&opnd,Pop(&opnd)-j);
						break;
					case '*':
						Push(&opnd,Pop(&opnd)*Pop(&opnd));
						break;
					case '/':
						j = Pop(&opnd);
						Push(&opnd,Pop(&opnd)/j);
						break;
				}
				continue;		
			}
		}
	}
	printf("结果是:%d\n",Pop(&opnd));
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pitepa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值