您的位置:首页 > 其它

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

2008-04-06 11:04 375 查看
/*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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: