zoukankan      html  css  js  c++  java
  • VC++2012编程演练数据结构《5》堆栈实现解析任意计算表达式

    栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。
      栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为后进先出表。
      栈可以用来在函数调用的时候存储断点,做递归时要用到栈!
      以上定义是在经典计算机科学中的解释。
      在计算机系统中,栈则是一个具有以上属性的动态内存区域。程序可以将数据压入栈中,也可以将数据从栈顶弹出。在i386机器中,栈顶由称为esp的寄存器进行定位。压栈的操作使得栈顶的地址增大,弹出的操作使得栈顶的地址减小。
      栈在程序的运行中有着举足轻重的作用。最重要的是栈保存了一个函数调用时所需要的维护信息,这常常称之为堆栈帧或者活动记录。堆栈帧一般包含如下几方面的信息:
      1. 函数的返回地址和参数

      2. 临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量。

    学过编译原理的人都知道解析任意计算表达式不是个轻松的活

    我们来用堆栈实际解决解析任意计算表达式

    打开IDE


    我们基于VC++2012创建一个工程


    堆栈头文件声名如下


    堆栈类实现如下




    我们来编写解析计算表达式代码如下,请见代码注释


    #include "stdafx.h"
    #include "stack.h"
    char OP[10]={'+','-','*','/','(',')','#'};
    int precede[7][7]={
    	1,1,2,2,2,1,1,
    		1,1,2,2,2,1,1,
    		1,1,1,1,2,1,1,
    		1,1,1,1,2,1,1,
    		2,2,2,2,2,3,0,
    		1,1,1,1,0,1,1,
    		2,2,2,2,2,0,3};
    	
    	int In(char c,char *op)
    	{ int i=0;
    	while(i<7)
    		if(c==op[i++]) return 1;
    		return 0;
    	}
    	char Precede(char op,char c)
    	{ int pos_op;
    	int pos_c;
    	int i;
    	for(i=0;i<7;i++)
        { if(op==OP[i]) pos_op=i;
    	if(c==OP[i]) pos_c=i;
        }
    	switch(precede[pos_op][pos_c])
        { case 1:  return '>';
    	case 2:  return '<';
    	case 3:  return '=';
        }
    	return 'A';
    	}
    	char Operate(int a,char theta,int b)
    	{ switch(theta)
        { case '+':return a+b-'0';
          case '-':return a-b+'0';
          case '*':return (a-'0')*(b-'0')+'0';
          case '/':return (a-'0')/(b-'0')+'0';
        }
    	return 'A';
    	}
    	char EvaluateExpression()
    	{ SqStack *OPND,*OPTR;
    	char c,x,theta;
    	char a,b;
    	OPTR->InitStack(&OPTR);
    	OPTR->Push('#');
    	OPND->InitStack(&OPND);
    	c=getchar();
    	while(c!='#'||OPTR->GetTop()!='#')
        {if(!In(c,OP))
    	{OPND->Push(c);c=getchar();}
    	else
    		switch(Precede(OPTR->GetTop(),c))
    	{case '<':
    	   OPTR->Push(c);
    	   c=getchar();break;
    	 case '=':
    		 OPTR->Pop(&x);
    		 c=getchar();break;
    	 case '>':
    		 OPTR->Pop(&theta);
    		 OPND->Pop(&b);OPND->Pop(&a);
    		 OPND->Push(Operate(a,theta,b));
    		 break;
    	}
        }
    	c=OPND->GetTop();
    	OPTR->DestroyStack();
    	OPND->DestroyStack();
    	return c;
    	}
    	void main()
    	{ char i;
    	printf("运行结果:\n");
    	printf("范围[0,9],输入以#号结束:");
    	i=EvaluateExpression();
    	cout<<"\n表达式的值是:";
    	cout<<i-'0'<<endl;
    	getch();
    	}
    


    计算效果如下,不限长度的任意计算表达式


    源码下载地址


    http://download.csdn.net/detail/yincheng01/4785610



  • 相关阅读:
    [LeetCode] 314. Binary Tree Vertical Order Traversal
    [LeetCode] 139. Word Break
    [LeetCode] 540. Single Element in a Sorted Array
    [LeetCode] 1443. Minimum Time to Collect All Apples in a Tree
    [LeetCode] 1442. Count Triplets That Can Form Two Arrays of Equal XOR
    [LeetCode] 1441. Build an Array With Stack Operations
    [LeetCode] 277. Find the Celebrity
    [LeetCode] 1232. Check If It Is a Straight Line
    [LeetCode] 10. Regular Expression Matching
    [LeetCode] 1192. Critical Connections in a Network
  • 原文地址:https://www.cnblogs.com/new0801/p/6177661.html
Copyright © 2011-2022 走看看