第三章(6).栈的应用举例(2)

以链栈基本操作为基础

//-----------------应用举例操作-------------------//
//Hanoi塔问题
void move( char x , int n , int z )

 static int c = 0 ;    //对搬动计数
 
 printf( "%i.Move disk %i from %c to %c\n" , ++c , n , x , z ) ;
}

void Hanoi( int n , char x , char y , char z )
{ //将塔座x上按直径由小到大且自上而下编号为1至n的n个圆盘按规则搬到塔座z上,y可做辅助塔座
 if( n == 1 )
  move( x , 1 , z ) ;    //将编号为1的圆盘从x移至z. 
 else
 {
  Hanoi( n-1 , x ,z , y ) ;  //将x上编号为1至n-1的圆盘移至y,z做辅助塔
  move( x , n , z ) ;    //将编号n的盘从圆盘从x移到z.
  Hanoi( n-1 , y , x , z ) ;
 }
}

//------------------------------------------------------//
//在此只讨论简单算术表达式的求值问题。(+,-,*,/)  因为数据元素也是以字符格式处理的,所以进行的元素为0-9之间.(如果想要改为处理任意数,则需对两个栈进行区别化处理)
ElemType Precede( ElemType theta , ElemType thetb )
{
 ElemType cmp ;
 switch( thetb )
 {
 case '+':
 case '-':if(theta =='('||theta=='#') cmp = '<';
    else cmp = '>' ; break ;
 case '*':
 case '/':if( theta=='*'||theta=='/'||theta==')') cmp = '>' ;
    else cmp = '<' ; break ;
 case '(':if(theta==')')
    {
     printf("ERROR!\n");
     exit( 0 ) ;
    }
    else cmp = '<' ; break ;
 case ')':if(theta=='(') cmp = '=' ;
    else{
     if(theta =='#')
     {
     printf("ERROR!\n");
     exit( 0 ) ;
     }
     else cmp = '>' ;
    }
    break ;
 case '#':if(theta=='(')
    {
     printf("ERROR!\n");
     exit( 0 ) ;
    }
    else
    {
     if(theta =='#') cmp = '='  ;
     else cmp = '>' ;
    }
    break ;
 }
 return cmp ;
}

ElemType Operate( ElemType a , ElemType theta , ElemType b )
{
 ElemType c ;
 a -= 48 ; b -= 48 ;
 switch( theta )
 {
 case '+': c = a+b+48 ; break ;
 case '-': c = a-b+48 ; break ;
 case '*': c = a*b+48 ; break ;
 case '/': if( b ) c = a/b+48 ; break ;
 }
 return c ;
}

//int In( ElemType c ,ElemType *OP )   //OP为运算符集,但在此处可以内置,因为我们进行的运算只是简单的几种算术运算
int In( ElemType c )
{
 if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#')
  return 1 ;
 return 0 ;
}

ElemType EvaluteExpression( )
{ //算数表达式求值的算符优先算法。OPTR和OPND分别为运算符栈和运算数栈,OP为运算符集合
 LinkStack OPTR , OPND ;
 ElemType a , b , c , x , theta;

 InitStack( &OPTR ) ; Push( &OPTR , '#' ) ; //运算符和运算数统一为字符格式,便于处理,不然两个栈就需要不同元素的类型.带来处理上的麻烦!
 InitStack( &OPND ) ; c = getchar( ) ;
 while( c != '#' || GetTop( OPTR )!= '#')
 {
  if( !In( c ) )       //不是运算符则进栈
  {
   Push( &OPND , c ) ;
   c = getchar( ) ;
  }
  else
  {
   switch( Precede( GetTop(OPTR) , c ) )
   {
   case '<':Push( &OPTR , c ) ; c = getchar( ) ; break ;  //栈顶元素优先级低
   case '=':Pop( &OPTR , &x ) ; c = getchar( ) ; break ;
   case '>':Pop( &OPTR , &theta ) ; Pop( &OPND , &a ) ; Pop( &OPND , &b ) ;Push( &OPND , Operate( b  , theta , a ) ) ;break ;
   }
  }
 }
 return GetTop( OPND ) ;
}
//---------------------------------------------------//
int  main( )
{
// char x , y , z ;
// Hanoi( 3 , 'x' , 'y' , 'z' ) ;

 printf( "%d\n" , EvaluteExpression( )- 48 );   //测试用例4+2*3-9/3#

 return 0 ;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值