栈实现的计算器 数据结构运用

这个  代码  只能实现是一个字符 一个字符输入

 

具体实现   比如  执行的18*6的这样的,我们可以用输入字符串的形式输入

遇到操作符就  进OPTR栈     否则a=ch[i]-'0';

然后再 将a  压入栈      具体实现   有兴趣的可以自己实现   有问题  请留言

我们来看下  实现这个部分的 源代码

double Run()
{
	 double ans=0.0;
     initstack(OPTR);
     push(OPTR,'#');
     initstack(OPND);
     char c;
     double re=0,op=0,a=0,b=0;//用来得到出栈返回值 
     c=getchar();//缺点 一次只能输入一次   输入10*2就不行了 后面只要是数字字符就出栈
     while (c!='#'||gettop(OPTR)!='#')
     {
           if (c>='0'&&c<='9')//这里只能输入一个字符了,如果是18*3 
           {
              push(OPND,c-'0');//进栈的时候先转换比后面转更好
              c=getchar();                
           }
           else
           {
			   int left=cmp(int(gettop(OPTR))),right=cmp(c);
			   //cout<<ch[left][right]<<endl;
              switch(ch[left][right])//分别获得gettop(OPTR) c对应的下标 
              {
                    case '<':
                         push(OPTR,c);
                         c=getchar();
                         break;
                    case '=':                 //去括号,进行运算 
                         pop(OPTR,re);
                         c=getchar();
                         break;
                    case '>':
                         pop(OPTR,op);//让运算符 出来
                         pop(OPND,b);
                         pop(OPND,a);
						 ans=Operate(a,op,b);
                         push(OPND,ans); 
					break;
              } 
           }
     }
	 return ans;
}

 

接下来是全部的源代码:  

#include <iostream>
#include <stdlib.h>
using namespace std;
const int MAX_SIZE=100;
struct stack    //这里里面的元素不适合字符类型比如8*8=? 
{
        double *base;
        double *top;
        int stacksize;
};
/**********************************\
   +   -   *   /   (   )   #
+ '>','>','<','<','<','>','>',
- '>','>','<','<','<','>','>',
* '>','>','>','>','<','>','>',
/ '>','>','>','>','<','>','>',
( '<','<','<','<','<','=',' ',
) '>','>','>','>',' ','>','>',
# '<','<','<','<','<',' ','=', 
\**********************************/
char ch[7][7]=
{'>','>','<','<','<','>','>',
 '>','>','<','<','<','>','>',
 '>','>','>','>','<','>','>',
 '>','>','>','>','<','>','>',
 '<','<','<','<','<','=',' ',
 '>','>','>','>',' ','>','>',
 '<','<','<','<','<',' ','=',
};

void initstack(stack &s)
{
     s.base=new double[MAX_SIZE];
     s.top=s.base;
     s.stacksize=MAX_SIZE;
}

void push(stack &s,double elem)
{
     if (s.top-s.base>MAX_SIZE)
     {
        s.base=new double [MAX_SIZE+MAX_SIZE];
        if (!s.base)
           return;
        s.top=s.base+s.stacksize;
        s.stacksize+=MAX_SIZE;                        
     }
     *s.top++=elem;
}

double pop(stack &s,double &elem)//这里pop和gettop是一个意思
{
     if (s.top==s.base)
        return -1;
     return elem=*--s.top;//
}

double gettop(stack &s)
{
    if (s.top==s.base)
       return -1;
    return *(s.top-1); //top指针指的是栈顶元素的下一个位置 
}
int cmp(int c)//比较两个运算符的优先关系  把其返回值和数组ch下标联系 
{
    int index;
     switch(c)
     {
           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;
                break;                  
     }
     return index;
}

double Operate(double a,int op, double b)  //这里操作符op是int型的,大家可以试下int s=65; s=='a'
{
	//a=a-48;//a=a-'0';
	//b=b-48;
    switch(op)
    {
          case '+':
               return 
				   a+b;
			   break;
          case '-':
               return a-b;
			   break;
          case '*':
               return a*b;
			   break;
          case '/':
               return a/b;//这里 要注意精度    
			   break;
    }
	return 0;
}
struct stack OPTR,OPND;//分别寄存运算符和操作数 
double Run()
{
	 double ans=0.0;
     initstack(OPTR);
     push(OPTR,'#');
     initstack(OPND);
     char c;
     double re=0,op=0,a=0,b=0;//用来得到出栈返回值 
     c=getchar();//缺点 一次只能输入一次   输入10*2就不行了 后面只要是数字字符就出栈
     while (c!='#'||gettop(OPTR)!='#')
     {
           if (c>='0'&&c<='9')//这里只能输入一个字符了,如果是18*3 
           {
              push(OPND,c-'0');//进栈的时候先转换比后面转更好
              c=getchar();                
           }
           else
           {
			   int left=cmp(int(gettop(OPTR))),right=cmp(c);
			   //cout<<ch[left][right]<<endl;
              switch(ch[left][right])//分别获得gettop(OPTR) c对应的下标 
              {
                    case '<':
                         push(OPTR,c);
                         c=getchar();
                         break;
                    case '=':                 //去括号,进行运算 
                         pop(OPTR,re);
                         c=getchar();
                         break;
                    case '>':
                         pop(OPTR,op);//让运算符 出来
                         pop(OPND,b);
                         pop(OPND,a);
						 ans=Operate(a,op,b);
                         push(OPND,ans); 
					break;
              } 
           }
     }
	 return ans;
}
void del(stack &s)
{
	delete []s.base;
	delete []s.top;
}
int main()
{
	double ans=0;
	int t;
	//cout<<"请输入您要计算表达式的次数:"<<endl;
	//cin>>t;
	while (1)
	{
	      ans=Run();
	      cout<<ans<<endl;
		  del(OPTR);
		  del(OPND);
		  //delete []OPTR.base;
		  //delete []OPTR.top;
		  //delete []OPND.base;
		  //delete []OPND.top;
		  system("pause");
	}
	return 0;
}




最后补上一句   这里的getchar换成  getch更好  就不会出现第二次输入 出现   死循环

因为 中间  有个换行   getchar不行   getch  是只读入字符的 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值