資料結構課程設計---計算器模擬器
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#define MaxSize 1000
#define MaxOp 1000
using namespace std;
struct charac //設定運算子優先順序
{
char ch; //運算子
int pri; //優先順序
};
struct charac lpri[]=//左運算子及優先順序
{
{'=',0},
{'(',1},
{'*',5},
{'/',5},
{'+',3},
{'-',3},
{')',8},
{'a',7},//a代表abs
{'q',7},//q代表sqrt
{'c',7},//c代表cos
{'%',5},//模運算
{'s',7},//s代表sin
{'t',7},//t代表tan
{'^',7},
{'!',7}//階乘
},
rpri[]=//右運算子及優先順序
{
{'=',0},
{'(',8},
{'*',4},
{'/',4},
{'+',2},
{'-',2},
{')',1},
{'a',6},
{'q',6},
{'c',6},
{'%',4},
{'s',6},
{'t',6},
{'^',6},
{'!',6}
};
int leftpri(char op) //求左運算子op的優先順序
{
int i;
for (i=0; i<MaxOp; i++)
if (lpri[i].ch==op) return lpri[i].pri;
}
int rightpri(char op) //求右運算子op的優先順序
{
int i;
for (i=0; i<MaxOp; i++)
if (rpri[i].ch==op) return rpri[i].pri;
}
bool InOp(char ch) //判斷ch是否為運算子
{
if (ch=='(' || ch==')' || ch=='+' || ch=='-'|| ch=='*' || ch=='/'||ch=='a'
||ch=='q'||ch=='c'||ch=='%'||ch=='s'||ch=='t'||ch=='^'||ch=='!')
return true;
else
return false;
}
int Precede(char op1,char op2) //op1和op2運算子優先順序的比較結果
{
if (leftpri(op1)==rightpri(op2))
return 0;
else if (leftpri(op1)<rightpri(op2))
return -1;
else
return 1;
}
void trans(char *exp,char postexp[])//將算術表示式exp轉換成字尾表示式postexp
{
struct
{
char data[MaxSize]; //存放運算子
int top; //棧指標
} op; //定義運算子棧
int i=0; //i作為postexp的下標
op.top=-1;
op.top++; //將'='進棧
op.data[op.top]='=';
while (*exp!='\0') //exp表示式未掃描完時迴圈
{
if (!InOp(*exp)) //為數字字元的情況或小數
{
while (*exp>='0' && *exp<='9'||*exp=='.') //判定為數字
{
postexp[i++]=*exp;
exp++;
}
postexp[i++]='#'; //用#標識一個數值串結束
}
else //為運算子的情況
switch(Precede(op.data[op.top],*exp))
{
case -1: //棧頂運算子的優先順序低:進棧
op.top++;
op.data[op.top]=*exp;
exp++; //繼續掃描其他字元
break;
case 0: //只有括號滿足這種情況
op.top--; //將(退棧
exp++;
break;
case 1: //退棧並輸出到postexp中
postexp[i++]=op.data[op.top];
op.top--;
break;
}
}
while (op.data[op.top]!='=') //將棧中運算子退到postexp中
{
postexp[i++]=op.data[op.top];
op.top--;
}
postexp[i]='\0'; //給postexp表示式新增結束標識
}
int fact(int n)//階乘
{
if(n==1)return 1;
return n*fact(n-1);
}
float compvalue(char exp[]) //計算字尾表示式的值
{
struct
{
float data[MaxSize]; //存放數值
int top; //棧指標
} st; //定義數值棧
float d;
char ch;
int t=0; //t作為exp的下標
st.top=-1;
ch=exp[t];
t++;
while (ch!='\0') //exp字串未掃描完時迴圈
{
switch (ch)
{
case '!':
st.data[st.top]=fact(st.data[st.top]);
break;
case '^':
st.data[st.top-1]=pow(st.data[st.top-1],st.data[st.top]);
st.top--;
break;
case 's':
st.data[st.top]=sin(st.data[st.top]);
break;
case 't':
st.data[st.top]=tan(st.data[st.top]);
break;
case '%':
st.data[st.top-1]=
(float)(((int)st.data[st.top-1])%((int)st.data[st.top]));
st.top--;
break;
case 'c':
st.data[st.top]=cos(st.data[st.top]);
break;
case 'a':
st.data[st.top]=abs(st.data[st.top]);
break;
case 'q':
st.data[st.top]=sqrt(st.data[st.top]);
case'+':
st.data[st.top-1]=
st.data[st.top-1]+st.data[st.top];
st.top--;
break;
case '-':
st.data[st.top-1]=
st.data[st.top-1]-st.data[st.top];
st.top--;
break;
case '*':
st.data[st.top-1]=
st.data[st.top-1]*st.data[st.top];
st.top--;
break;
case '/':
if (st.data[st.top]!=0)
st.data[st.top-1]=
st.data[st.top-1]/st.data[st.top];
else
{
printf("\n\t除零錯誤!\n");
exit(0); //異常退出
}
st.top--;
break;
default:
d=0;
int flag=0,count=0; //將數字字元轉換成數值存放到d中
while (ch>='0' && ch<='9'||ch=='.') //為數字字元
{
if(ch=='.')flag=1;
if(flag==0)
{
d=10*d+ch-'0';
}
else
{
if(ch<='9'&&ch>='0')
d=d+(ch-'0')/pow(10,count);
count++;
}
ch=exp[t];
t++;
}
st.top++;
st.data[st.top]=d;
}
ch=exp[t];
t++;
}
return st.data[st.top];
}
bool checkbracket(char *exp,int n)
{
int i=0;
bool match=true;
struct
{
char data[MaxSize]; //存放數值
int top; //棧指標
} st;
st.top=-1;
while(i<n&&match)
{
if(exp[i]=='(')
{
st.top++;
st.data[st.top]=exp[i];
}
else if(exp[i]==')')
{
if(st.top!=-1)
if(st.data[st.top]!='(')
match=false;
else st.top--;
else match=false;
}
i++;
}
if(st.top!=-1)
match=false;
return match;
}
bool check(char *exp,int n)
{
int i=0,match=true;
while(*exp!='\0'&&i<n&&match)
{
if(*exp<='9'&&*exp>='0'||*exp=='.'||InOp(*exp)==true)
;
else
match=false;
i++;
}
return match;
}
int main()
{
system("簡易計算器");
system("mode con cols=90 ");
printf("=================簡易計算器==================\n");
printf(" * 本計算器支援整型、浮點型數運算\n");
printf(" * 本計算器支援四則運算、sqrt、abs\n cos、sin、tan、mod、^運算及階乘運算\n");
printf(" * sin用s表示,cos用c表示,tan用t表示\n");
printf(" * abs用a表示,sqrt用q表示\n");
printf(" * ^表示平方,!表示階乘\n");
printf("==============================================\n");
printf("請輸入表示式\n");
char exp[100];
char postexp[MaxSize],c='y';
while(c=='y')
{
gets(exp);
int n=strlen(exp);
if(n==0)printf("沒有任何輸入,請重新輸入\n");
else
{
if(!checkbracket(exp,n))printf("表示式括號不匹配,請重新輸入!\n");
else if(!check(exp,n))printf("表示式中出現無法識別符號,請重新輸入!\n");
else
{
trans(exp,postexp);
printf("字尾表示式:%s\n",postexp);
printf("表示式的值:%g\n",compvalue(postexp));
}
}
printf("繼續請輸入y,任意鍵退出");
scanf("%c",&c);
getchar();
}
return 0;
}