#include<malloc.h>
#include<iostream.h>
#include <string.h>
#include<stdlib.h>
#define max 100
typedef float SElemType;
typedef struct
{ 
	char stack[max];
    int top;
}Stack1;  //创建运算符栈
typedef struct
{ 
	SElemType stack[max];
	int top;
}Stack2;  //创建操作数栈*/
int In(char c)//判断c是否为七种运算符之一
{
	switch(c)
	{
	case'+':
	case'-':
	case'*':
	case'/':
	case'(':
	case')':
	case'#':
		return 1;
		break;
	default:
		return 0;
	}//switch
}
void initStack1(Stack1 *S)  //初始化栈Stack1
{
  S->top=-1;
}
void initStack2(Stack2 *S)
{
   S->top=-1;
}

void Push1(Stack1 *S,char ch)  //将运算符进栈
{
   	if((S->top<max-1)&&(S->top>=-1))
	{ 
		(S->top)++;
        S->stack[S->top]=ch;
	}
    else   
{	printf("error!\n");}
}
void Push2(Stack2 *S,SElemType ch)   //将操作数进栈
{
 	if((S->top<max-1)&&(S->top>=-1))
	{ 
		(S->top)++;
        S->stack[S->top]=ch;
	
	}
    else  
	printf("error!\n");
}

char Precede(char ch1,char ch2)  //比较运算符的优先级
{
  char ch;  //定义ch表示操作符比较后的值赋值给ch:'>'和'<'
  switch(ch1)
  {
  case'+'://此处由于加减几乎优先级一样,故放在一起
  case'-':
	  if((ch2=='*')||(ch2=='/')||(ch2='(')||(ch2='#'))
		  ch='<';
	  else
		  ch='>';
	  break;
  case'*': 
  case'/':
	  if((ch2=='*')||(ch2='/')||(ch2=')'))
          ch='>';
	  else
		  ch='<';
	  break;
    case'(':
	  if(ch2=')')
	  ch='='; 
	  else if(ch2='#')
	  {printf("没有左括号!\n");}
      else
		 ch='>';
       break;
	 case')':
		 if(ch2=='(')
		 {
			 printf("括号匹配错误!\n");
		 }
			 else
				 ch='<';
			 break;
    case'#':
	switch(ch2)
	{
	case'#': 
		ch='=';
		break;
	case'(':
		printf("error!没有右括号");
		break;
	default:
		ch='>';
	}

  }
  return ch;
}

void Pop1(Stack1 *S,char *p)  //比较后将优先级较高的运算符出栈
{
	if(S->top>=0)
	{
      *p=S->stack[S->top];
      (S->top)--; 
	 
	}
    else 
	   printf("error!\n");
}
void Pop2(Stack2 *S,SElemType *p)   //将操作数出栈
{

    if(S->top>=0)
	{
      *p=S->stack[S->top];
      (S->top)--; 
	 
	}
    else 
	printf("error!\n");
	
}

char gettop1(Stack1 *S)   //运算符取栈顶元素
{
   return S->stack[S->top];
 
}
float gettop2(Stack2 *S)  //操作数取栈顶元素
{

    return S->stack[S->top];
 
}

void ClearStack1(Stack1 *S) //清空栈
{
   S->top=-1;
}
void ClearStack2(Stack2 *S)
{
   S->top=-1;
}

SElemType Operate(SElemType a,char a1,SElemType b)   //表达式的计算
{
  // char n=char(a1);
	float s;
   switch(a1)
   {
   case'+':
	   s=a+b;
	   break;
   case'-':
	   s=a-b;
	   break;
   case'*':
	   s=a*b;
   case'/':
	  if(b==0)
	   {
	     printf("\n表达式输入错误!\n");
	   }
	   else 
	   { s=a/b;}
	   break;
   }
   return s;
}

SElemType Expression()
{ 
	char Data[20];   //定义此数组为了存放整数或小数
    SElemType a,b,a1; 
	int d;
    char c,x; 
	Stack1 optr1,*optr=&optr1;
     Stack2 opnd1,*opnd=&opnd1;
     initStack1(optr);   //初始化运算符栈
      Push1(optr,'#');     //表达式起始符进栈
     initStack2(opnd);   //初始化操作数栈 
	 c=getchar();
    x=gettop1(optr);

     while((c!='#')||(gettop1(optr)!='#'))  //'#'也是表达式的截止符
    {   
        if(in(c))   
        {   
           switch(Precede(gettop1(optr),c))  // 若当前输入字符为运算符,比较其与optr栈顶运算符的优先级
		   {
	      case'<':  //表示当前运算符的优先级大于optr栈顶元素的优先级,则当前运算符进栈
		    Push1(optr,c);
		     c=getchar();
		    break;
	      case'=':
	 	    Pop1(optr,&x);  //操作符栈顶元算出栈
		    c=getchar();
		    break;
	      case'>':
		    Pop1(optr,&x);  //操作符栈顶元素出栈
		    Pop2(opnd,&b);   //操作数栈顶元素出栈
		    Pop2(opnd,&a);   //操作数栈顶元素出栈
		   Push2(opnd,Operate(a,x,b));   //运算结果进栈
		    break;
		   }
		}
			
		else if(c>='0'&&c<='9'||c=='.')
		{
			int i=0;
			while(c>='0'&&c<='9'||c=='.')
			{
				Data[i]=c;
				i++;
				c=getchar();
			}
			Data[i]='\0';///数字没有存满,输入字符串结束符
			a1=atof(Data);//此处是把数组里的数字,实际上是按字符串;转换为double类型,然后把浮点型数字入栈
            Push2(opnd,a1);//atof函数的形参是指针类型,故用数组名
        }  
		else
		{printf("error!输入错误!\n");}
		gettop1(optr);
	 }
	return  gettop2(opnd);
    
 
}
 
int main()
{ 
 // char s[max];
   SElemType result;
   char choice;
 printf("************欢迎进去表达式求解程序************\n");
L: printf("请输入您的算术表达式,且以#结束:\n");
  // gets(s);
    result=Expression();
	printf("\n表达式的计算结果为:%d\n",result);
     printf("Do you want to continue:");
	  scanf(" %c",&choice);
	 if(choice=='Y'||choice=='y')
        goto L;
	 else
 	printf("\n************感谢使用表达式求解程序************\n");
   return 0;
}