用链栈实现的功能强大的计算器

/*LinkStack.h头文件*/

#include <stdlib.h>

#define TRUE 1
#define FALSE 0
#define NULL 0

typedef double ElementType;
typedef int Status;

typedef struct node{
    ElementType data;
    struct node *next;
}StackNode, *LinkStack;

void InitStack(LinkStack &head){
 head=(StackNode *)malloc(sizeof(StackNode));
    head->next = NULL;
}

status IsEmpty(LinkStack head){
    if(head->next == NULL) return TRUE;
    return FALSE;
}

status Push(LinkStack head, ElementType element){
    StackNode *newp;
    newp = (StackNode *)malloc(sizeof(StackNode));
    if(newp == NULL) return FALSE;
    newp->data = element;
    newp->next = head->next;
    head->next = newp;
    return TRUE;
}

StatusPop(LinkStack head, ElementType &element){
    if(IsEmpty(head)) return FALSE;
    StackNode *newp = head->next;
    element = newp->data;
    head->next = newp->next;
    free(newp);
    return TRUE;
}

void GetTop(LinkStack head, ElementType &element){
 if(head->next==NULL)
  element=0;
    element = head->next->data;
}

Status DestroyStack(LinkStack &head)
{
 LinkStack q;
 while(head)
 {
 q=head->next;
 delete head;
 head=q;
}
 return TRUE;

 

/*LinkStack_Char.h头文件*/

#include <stdlib.h>

#define TRUE 1
#define FALSE 0
#define NULL 0

typedef char ElemType;
typedef int Status;

typedef struct node1{
    ElemType data;
    struct node1 *next;
}StackCharNode, *LinkCharStack;

void InitStack(LinkCharStack &head){
 head=(StackCharNode *)malloc(sizeof(StackCharNode));
    head->next = NULL;
}

int IsEmpty(LinkCharStack head){
    if(head->next == NULL) return TRUE;
    return FALSE;
}

int Push(LinkCharStack head, ElemType element){
    StackCharNode *newp;
    newp = (StackCharNode *)malloc(sizeof(StackCharNode));
    if(newp == NULL) return FALSE;
    newp->data = element;
    newp->next = head->next;
    head->next = newp;
    return TRUE;
}

int Pop(LinkCharStack head, ElemType &element){
    if(IsEmpty(head)) return FALSE;
    StackCharNode *newp = head->next;
    element = newp->data;
    head->next = newp->next;
    free(newp);
    return TRUE;
}

int GetTop(LinkCharStack head, ElemType &element){
 if(head->next!=NULL)
 {element = head->next->data;
 return TRUE;}
 element='#';
 return FALSE;
}

Status DestroyStack(LinkCharStack &head)
{
 LinkCharStack q;
 while(head)
 {
 q=head->next;
 delete head;
 head=q;
}
 return TRUE;
}

//Calculator.cpp

/*
此算法的基本思想:
    首先置操作数栈为空栈,表达式起始符“#”为运算符的栈底元素;
 依次读入表达式中每个字符,若是操作数则进栈,若是运算符则和OPTR栈
 的栈顶运算符比较优先权作相应操作,直至整个表达式求值完毕(即OPTR栈的栈顶元素和当前读入的字符均为“#”)
*/
# include <stdio.h>
# include <iostream.h>
# include <string.h>
# include <stdlib.h>
# include "LinkStack.h"
# include "LinkStack_char.h"

# define STACK_INIT_SIZE 30
# define STACKINCREAMENT 10
# define NUMBER 30


//判断ch是否为运算符
int Comop(char ch)
{
 switch(ch)
 {
  case '+':
  case '-':
  case '*':
  case '/':
  case '(':
  case ')':
  case '#':return 1;
  default:return 0;
 }
}//Comop

/*void change(char *exp)
{
 int i=0;
 if()
}
*/
//比较两个运算符的优先级
char precede(char ch,char c)//ch是栈顶字符,c 是表达式字符
{
 switch(ch)
 {
 case '+':
  if(c=='+')return '>';
  if(c=='-')return '>';
  if(c=='*')return '<';
  if(c=='/')return '<';
  if(c=='(')return '<';
  if(c==')')return '>';
  if(c=='#')return '>';
 case '-':
  if(c=='+')return '>';
  if(c=='-')return '>';
  if(c=='*')return '<';
  if(c=='/')return '<';
  if(c=='(')return '<';
  if(c==')')return '>';
  if(c=='#')return '>';
 case '*':
  if(c=='+')return '>';
  if(c=='-')return '>';
  if(c=='*')return '>';
  if(c=='/')return '>';
  if(c=='(')return '<';
  if(c==')')return '>';
  if(c=='#')return '>';
 case '/':
        if(c=='+')return '>';
  if(c=='-')return '>';
  if(c=='*')return '>';
  if(c=='/')return '>';
  if(c=='(')return '<';
  if(c==')')return '>';
  if(c=='#')return '>';
 case '(':
  if(c=='+')return '<';
  if(c=='-')return '<';
  if(c=='*')return '<';
  if(c=='/')return '<';
  if(c=='(')return '<';
  if(c==')')return '=';
  if(c=='#')return ' ';
 case ')':
  if(c=='+')return '>';
  if(c=='-')return '>';
  if(c=='*')return '>';
  if(c=='/')return '>';
  if(c=='(')return ' ';
  if(c==')')return '>';
  if(c=='#')return '>';
 case '#':
  if(c=='+')return '<';
  if(c=='-')return '<';
  if(c=='*')return '<';
  if(c=='/')return '<';
  if(c=='(')return '<';
  if(c==')')return ' ';
  if(c=='#')return '=';
 default:
  return '$';
 }
}//precede

//错误提示函数
int error(char *str)   //在测试过程中可以不断扩充错误的类型

 int i=0,err=0;
  while(str[i]!='#') //主要通过判断所有输入的字符数组str[30]
 {
 if( err==1  //err是为有些字符并不满足其它函数而设的一个错误点                                                  
     ||(
     (str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/'||str[i]=='.')  
     &&        //其它函数只要一声明err=1也就说明输入有误
     (str[i+1]==')')
       )
     ||(
        (str[i]=='+'||str[i]=='*'||str[i]=='/'||str[i]=='.')
     &&
     (str[i-1]=='(')
       )
     ||(str[i]==')' && str[i+1]=='.')
     ||(str[i]=='.' && str[i+1]=='(')
     ||(str[i]==')' && str[i+1]=='(')
     ||(str[i]=='(' && str[i+1]==')')
     ||(str[0]=='+'||str[0]=='*'||str[0]=='/'||str[0]==')')                                
     ||(
     (str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/'||str[i]=='.')  
     &&
     (str[i+1]=='+'||str[i+1]=='-'||str[i+1]=='*'||str[i+1]=='/'||str[i+1]=='.'))
   
     ||(int(str[i])>57)
     ||(str[i]=='/' && str[i+1]=='0')
     ||(int(str[i])>31 && int(str[i])<38)
     )
    {  
     cout<<"您输入的表达式有误!"<<endl;
    return 1;
    }
   else if(str[i]=='#')return 0;
   i++;
 }
  return 0;
 
}//错误提示函数

//运算函数
ElementType Operate(ElementType a,char ch,ElementType b)
{
 switch(ch)
 {
 case '+':
  return a+b;
 case '-':
  return a-b;
 case '*':
  return a*b;
 case '/':
  if(b==0)
  {return -32767;}
  return a/b;
 default:
  return -32767;
 }
}//Operate

//表达式计算

ElementType EvaluateExpression(char *exp){
 LinkCharStack OPTR;//运算符栈
 LinkStack OPND;//操作数栈
 char c,ch,*p=exp,*q=p,*temp;//c代表输入表达式中的字符,ch代表栈顶运算符,temp指向运算符后面的一个字符
 double i=0,a=0,b=0;
 InitStack(OPTR);
 InitStack(OPND);
 c=*p;temp=p;p++;
// GetTop(OPTR,ch);
 if(c=='-')
 {
 // Push(OPND,0);
  c=*p;temp=p;p++;
 }
 while(c!='#'||!IsEmpty(OPTR))
 {//栈不为空或者表达式没有结束
  if(!Comop(c))
  {//不是运算符则解析数字字符串进操作数
      double m=0,n=0;
   while(c!='.'&&c>='0'&&c<='9')
   {//解析整数部分
    m=m*10+(c-48);
    c=*p;
    p++;
   }
   if(c=='.')
   {//解析小数部分
    c=*p;//p++;
    while(c>='0'&&c<='9')
    { p++;c=*p;}
    q=p;
    p--;
    while(*p!='.')
    {
     n=n/10+(*p-48)/10.0;
     p--;
    }
    p=q;
    p++;
   }
  // else q=p;   
  // c=*p;
  // p++;
   if(*(temp-2)=='('&&*(temp-1)=='-'||temp-1==exp)
    Push(OPND,-(m+n));
   else
   Push(OPND,m+n);
  }
  else
  {
   if(c=='-'&&*(p-2)=='(')
   {
    c=*p;
    temp=p;
    p++;    
   }
   else
   {
       GetTop(OPTR,ch);
   switch(precede(ch,c))
   {
       case '<'://栈顶运算符优先权低
        Push(OPTR,c);c=*p;temp=p;p++;
        break;
       case '='://脱括号并接收下一个字符
        Pop(OPTR,ch);c=*p;temp=p;p++;
        break;
       case '>':
        Pop(OPTR,ch);
        Pop(OPND,b);   Pop(OPND,a);
         Push(OPND,Operate(a,ch,b));
   //  GetTop(OPTR,ch);
        break;
       default:
   // cout<<"您输入的表达式有误!"<<endl;
        c=*p;temp=p;p++;
   }
   }//switch
  }
 }//while
 GetTop(OPND,i);
 DestroyStack(OPND);
 DestroyStack(OPTR);
return i;
}


//清屏函数
void Clear()
{
// char a;
// cout<<"请按 回车键 继续……"<<endl;
// a=getchar();
 system("cls");
}//清屏函数

 //菜单函数
void MenuPrint()
{
 cout<<"***********多功能计算器*************"<<endl;
 cout<<"/t 1计算"<<endl;
 cout<<"/t 2清屏"<<endl;
 cout<<"/t 3退出"<<endl;
 cout<<"请输入你要进行的操作(1-3)"<<endl;
} //菜单函数

void main()
{
 double result=0;
 char exp[NUMBER],c=1;
 while(1)
 {
 /* int i=0;
   char c=0;
   while(c!='#')
   {
   
    c=getchar();
    exp[i]=c;
    i++;
   }
 */
 MenuPrint();
 cin>>c;  
 switch(c)
 {
 case '1':
  cout<<"输入要计算的表达式,以#结束"<<endl;
     scanf("%s",exp);
     if(error(exp)==0)
  {
   result=EvaluateExpression(exp);
            cout<<"计算结果为:"<<result<<endl<<endl;
  }
  break;
 case '2':
  Clear();
  break;
 case '3':
  exit(0);
 default:
  cout<<"您的选择有误!"<<endl;
 }
 }
}//main

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值