栈的应用 算术表达式求值 学习笔记

//SeqStack.h
typedef struct stack
{
	DATA data[SIZE+1];  //数据元素 
	int top;  //栈顶 
}SeqStack;
SeqStack *SeqStackInit()
{
	SeqStack *p;
	if(p=(SeqStack *)(malloc)(sizeof(SeqStack)))  //申请栈内存 
	{
		p->top = 0; //设置栈顶为零 
		return p; //返回指向栈的指针 
	}
	return NULL;
}
int SeqStackIsEmpty(SeqStack *s) //判断栈是否为空 
{
	return(s->top==0);
}
void SeqStackFree(SeqStack *s)  //释放栈所占用空间
{
	if(s)
		free(s);
 } 
void SeqStackClera(SeqStack *s) // 清空栈
{
	s->top = 0;
 } 
int SeqStackFull(SeqStack *s)  //判断栈是否已满 
{
	return(s->top==SIZE) ;
}
int SeqStackPush(SeqStack *s, DATA data) // 入栈操作
{
	if((s->top+1)>SIZE)
	{
		printf("栈溢出!\n");
		return 0;
	}
	s->data[++s->top] = data; //栈元素入栈
	return 1; 
 } 
DATA SeqStackPop(SeqStack *s)  //出栈操作
{
	if(s->top==0)
	{
		printf("栈为空!");
		exit(0);
	}
	return (s->data[s->top--]);
}
DATA SeqStackPeek(SeqStack *s) // 读栈顶数据
{
	if(s->top==0)
	{
		printf("栈为空! ");
		exit(0);
	}
	return (s->data[s->top]);
 }
//CalcExp.c
#include<stdio.h> 
#include<stdlib.h>
#define SIZE 50
typedef int DATA;
#include "SeqStack.h"
int IsOperator(char c) // 检查字符是否为运算符
{
	switch(c)
	{
		case‘+‘:
		case‘-‘:
		case‘*‘:
		case‘/‘:
		case‘(‘:
		case‘)‘:
		case‘=‘:
			return 1;
			break;
		default:
			return 0;
			break;
	}
}
int PRI(char oper1,char oper2) // 判断两个运算符的优先级
//opera1>oper2 返回1
//oper1<oper2 返回-1
//oper1=oper2 返回0
{
	int pri;
	switch(oper2) //判断运算符优先级
	{
		case ‘+‘:
		case ‘-‘:
			if(oper1==‘(‘ || oper1==‘=‘)// 为左括号或表达式开始符号
				pri = -1; // 返回小于
			else
				pri = 1;
			break;
		case ‘*‘:
		case ‘/‘:
			if(oper1==‘*‘||oper1==‘/‘||oper1==‘)‘) 
				pri = 1;
			else
				pri=-1;
			break;
		case ‘(‘:
			if(oper1==‘)‘)  // 右括号右侧不能马上出现左括号
			{
				printf("语法错误!\n");
				exit(0);
			 } else
			 	pri=-1;
			break;
		case ‘)‘:
			if(oper1==‘(‘)
				pri = 0;
			else if(oper1==‘=‘)
			{
				printf("括号不匹配!\n");
				exit(0);
			}else
				pri=1;
			break;
		case ‘=‘:
			if(oper1==‘(‘)
			{
				printf("括号不匹配!\n");
				exit(0);
			}else if(oper1==‘=‘)
				pri =0;
			else
				pri =1;
			break;
	 } 
	 return pri;
}
int Calc(int a, int oper ,int b) // 计算两个操作数的结果
{
	switch(oper)
	{
		case ‘+‘: return a+b;
		case ‘-‘: return a-b;
		case ‘*‘: return a*b;
		case‘/‘:
			if(b!=0)
				return a/b;
			else
			{
				printf("除0溢出!\n");
				exit(0);
			}
	}
 } 
int CalcExp(char exp[]) // 表达式计算函数
{
	SeqStack *StackOper ,*StackData;
	int i=0,flag=0;
	DATA a,b,c,q,x,t,oper;

	StackOper = SeqStackInit();//初始化两个栈 
	StackData = SeqStackInit();

	q=0;
	x=‘=‘;
	SeqStackPush(StackOper, x); //首先将等号(=)进入操作符栈 
	x=SeqStackPeek(StackOper);//获取操作符栈的首元素 
	c=exp[i++];
	while(c!=‘=‘||x!=‘=‘)
	{
		if(IsOperator(c)) // 若输入的是运算符
		{
			if(flag){
				SeqStackPush(StackData,q); // 将操作符入栈
				q=0 ;
				flag = 0;
			}
			switch(PRI(x,c))//判断运算符的优先级
			{
				case -1:
					SeqStackPush(StackOper,c);//运算符进栈
					c=exp[i++] ;
					break;
				case 0:
					c = SeqStackPop(StackOper);//运算符出栈(抛弃) 
					c=exp[i++];
					break;
				case 1:
					oper = SeqStackPop(StackOper); //运算符出栈
					b=SeqStackPop(StackData); // 两个操作符出栈 
					a=SeqStackPop(StackData);
					t=Calc(a,oper,b);
					SeqStackPush(StackData,t);//将运算结果入栈
					break; 
			 } 
		 } else if(c>=‘0‘ && c<=‘9‘) // 若输入字符在0-9之间
		 {
		 	c-=‘0‘;
		 	q=q*10+c;
		 	c=exp[i++];
		 	flag=1;
		  } 
		  else
		  {
		  	printf("输入错误!\n");
		  	getch();
		  	exit(0);
		  }
		  x=SeqStackPeek(StackOper);//获取栈顶的运算符 
	}
	q=SeqStackPop(StackData) ;
	SeqStackFree(StackOper);//释放栈所占用的空间
	SeqStackFree(StackData); 
	return q; // 出栈,返回结果 
 } 
 
 int main()
 {
 	int c;
 	char exp[80];
 	printf("请输入要计算的表达式(以=结束):");
 	scanf("%s",exp);
 	printf("%s%d\n",exp,CalcExp(exp));
 	getch();
 	return 0;
 }
时间: 2024-10-12 18:31:49

栈的应用 算术表达式求值 学习笔记的相关文章

栈的应用—算术表达式求值

例三.算术表达式求值 1.问题描述 当一个算术表达式中含有多个运算符,且运算符的优先级不同的情况下,如何才能处理一个算术表达式????? 2.思路 首先我们要知道表达式分为三类:  ①中缀表达式:a+(b-c/d)*e ②前缀表达式+a*-be ③后缀表达式abcd/-e*+ 由于运算符有优先级,所以在计算机中计算一个中缀的表达式非常困难,特别是带括号的更麻烦,而后缀表达式中既无运算符优先又无括号的约束问题因为在后缀表达式中运算符出现的顺序正是计算的顺序,所以计算一个后缀的表达式更简单.所以,可

Dijkstra的双栈算术表达式求值

import java.util.Stack; import java.util.Scanner; public class Evaluate { public static void main(String[] args) { Stack<String> ops=new Stack<String>(); Stack<Double> vals=new Stack<Double>(); Scanner cin=new Scanner(System.in); /

算法手记(2)Dijkstra双栈算术表达式求值算法

这两天看到的内容是关于栈和队列,在栈的模块发现了Dijkstra双栈算术表达式求值算法,可以用来实现计算器类型的app. 编程语言系统一般都内置了对算术表达式的处理,但是他们是如何在内部实现的呢?为了了解这个过程,我们可以自行搭建一套简易的算术表达式处理机制,这里就用到栈特性和本篇提到的Dijkstra算法. 概述:     算术表达式可能是一个数.或者是由一个左括号.一个算术表达式.一个运算符.另一个算术表达式和一个右括号组成的表达式.为了简化问题,这里定义的是未省略括号的算术表达式,它明确地

【算法】E.W.Dijkstra算术表达式求值

算术表达式求值 我们要学习的一个栈的用例同时也是展示泛型的应用的一个经典例子,就是用来计算算术表达式的值,例如 ( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) ) 如果将4乘以5,把3加上2,取它们的积然后加上1,就得到了101.但Java系统是如何完成这些运算的呢?不需要研究Java系统的构造细节,我们也可以编写一个Java程序来解决这个问题.它接受一个输入字符串(表达式)并输出表达式的值.为了简化问题,首先来看一下这份明确的递归定义:算术表达式可能是一个数,或者是由一个左括号

数据结构 -- 整数算术表达式求值 (C/C++)

数据结构题集(C语言版)--严蔚敏,吴伟民编著 设置运算符栈和运算数栈辅助分析运算符有限关系. 读入表达式的字符序列的同时完成运算符和运算数(整数)的识别处理,以及相应的运算. 在识别出运算数的同时,要将其字符序列形式转换成整数形式. 1 /** 2 Function:整数算术表达式求值 3 Date:2014-11-10 4 Author:JackDawson 5 Compiler:gcc version 4.8.1 6 */ 7 #include <iostream> 8 #include

page80-栈用例-算术表达式求值

表达式由括号, 运算符和操作数(数字)组成.我们根据以下4中情况从左到右逐个将这些实体送入栈处理. (1)将操作数压入操作数栈: (2)将运算符压入运算符栈: (3)忽略左括号: (4)在遇到右括号时, 弹出一个运算符,弹出所需数量的操作符,并将运算符和操作符的运算结果压入操作数栈. [地杰斯特拉的双栈算术表达式求值算法] public class Evaluate { public static void main(String[] args) { Stack<String> ops = n

11、蛤蟆的数据结构笔记之十一栈的应用之表达式求值实现

11.蛤蟆的数据结构笔记之十一栈的应用之表达式求值实现 本篇名言:"人生不售来回票,一旦动身,绝不能复返." 继续栈应用实现,这次是来看下表达式求值的栈实现. 欢迎转载,转载请标明出处: 1.  表达式求值 表达式求值是设计语言编译中的一个基本问题,它的实现是栈应用的又一个典型例子. 任何一个表达式都是由操作数(Operand).运算符(operator)和界限符(delimiter)组成. 操作数可以是常数也可以是变量或变量的标识符. 运算符可以分为算术运算符.关系运算符和逻辑运算符

数据结构(7)----栈与队列之栈的应用四则运算表达式求值

栈与队列之栈的应用四则运算表达式求值 栈在四则运算表达式求值的应用为逆波兰表达式(后缀表达式) 普通算式(中缀表达式):9 + (3 - 1) * 3 + 10 / 2     ---(1) 逆波兰表达式(后缀表达式):9 3 1 - 3 * + 10 2 /         ---(2) 1:逆波兰表达式的计算规则 从左到右遍历表达式的每个数字和符号,遇到数字就进栈,遇到符号,就将处于栈顶的两个数字出栈,进行运算,再把运算结果进栈,一直到最终获得结果.接下来我们以(2)式为例:

简单算术表达式求值

#include <stdio.h> #include <string.h> int main() { int n,i; char a[200]; int f=0,l=0; gets(a); for(i=0;i<strlen(a);i++) { if(a[i]>='0'&&a[i]<='9')//如果是数字 { if(a[i+1]>='0'&&a[i+1]<='9')//如果后面那个也是数字 { f=(f+a[i]-48