|
发表于 2003-7-13 15:57:06
|
显示全部楼层
[code:1]
/*......calculator.......
author:hibernate
compile:in visual c++ and pass
input:illegal expression,including '+','-','*','/','sin','cos','tan' and 'ctg'
output:the result
......addition:It is a simple calculator,and there must be many bugs
If you find,please point them out.And you can email me:
My email:[email protected]
......ends........
*/
#include"math.h"
#include"stdlib.h"
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#define Size 50
#define sm 200
int Error1=0;
int precedent(char op);
int judge2(char ch);
double change(char* s1, char* s2);
//定义一个栈类,实现一个基本功能
template <typename T>
class Stack
{
private:
int size;
int top;
T* list;
public:
Stack()
{
size=sm;top=0;list=new T[size];
}
~Stack(){delete []list;}
void push(const T &item)
{
list[top++]=item;
}
bool isempty()
{
return top==0;
}
T pop()
{
return list[--top];
}
T topvalue()
{
return list[top-1];
}
void clean()
{
top=0;
}
};
/*
功能描述:计算出操作数的值
参数说明:为操作数的原始字符串
返回值:操作数的值,double类型
*/
double compute1(char *a)
{
bool sign=false;
bool point=false;
int i=0;
int type;
int power=0;
double reval=0;
char *temp=(char *)calloc(Size,sizeof(char));
char *temp1=(char *)calloc(Size,sizeof(char));
if(a[i]=='-')
{
sign=true;
i++;
}
for(;i<(int)strlen(a);i++)
{
type=judge2(a[i]);
if(type==1)
if((a[0]=='-'&&i==1)||i==0)
{
Error1=-1;
printf("Error1: some '.' shouldn't be placed there!Please check it!\n");
return -1;
}
else
point=true;
else if(type==2)
{
reval=reval*10+(a[i]-'0');
if(point)
power++;
}
else if(type==3)
{
if((a[i+1]=='i'||a[i+1]=='I')&&(a[i+2]=='n'||a[i+2]=='N')&&a[i+3]=='(')
{
i=i+4;
int left=1,right=0;
double value;
// char *temp=(char *)calloc(Size,sizeof(char));
// char *temp1=(char *)calloc(Size,sizeof(char));
for(int j=0;j<Size;j++)
{
if(a[i]=='(')
left++;
else if(a[i]==')')
right++;
if(right==left)
break;
temp[j]=a[i++];
}
temp[j++]='@';
temp[j]='\0';
if(j>Size)
{
Error1=-2;
printf("Error1:in the sin insides is too long!\n");
return -1;
}
value=change(temp,temp1);
reval=sin(value);
}
else
{
Error1=-1;
printf("Error1:no sign like this:%c%c%c!\n",a[i],a[i+1],a[i+2]);
return -1;
}
}
else if(type==4)
{
if(((a[i+1]=='o'||a[i+1]=='O')&&(a[i+2]=='s'||a[i+2]=='S')&&a[i+3]=='(')||
((a[i+1]=='t'||a[i+1]=='T')&&(a[i+2]=='g'||a[i+2]=='G')&&a[i+3]=='('))
{
char ch=a[i+1];
i=i+4;
int left=1,right=0;
double value;
// char *temp=(char *)calloc(Size,sizeof(char));
// char *temp1=(char *)calloc(Size,sizeof(char));
for(int j=0;j<Size;j++)
{
if(a[i]=='(')
left++;
else if(a[i]==')')
right++;
if(right==left)
break;
temp[j]=a[i++];
}
temp[j++]='@';
temp[j]='\0';
if(j>=Size)
{
Error1=-2;
if(ch=='o'||ch=='O')
printf("Error1:in the cos insides is too long!\n");
else
printf("Error1:in the ctg insides is too long!\n");
return -1;
}
value=change(temp,temp1);
if(ch=='o'||ch=='O')
reval=cos(value);
else
{
value=tan(value);
if(value==0)
{
Error1=3;
printf("Error1:the ctg argument value shouldn't be 0!\n");
return -1;
}
else
reval=1/value;
}
}
else
{
Error1=-1;
printf("Error1:no sign like this:%c%c%c\n",a[i],a[i+1],a[2]);
return -1;
}
}
else if(type==5)
{
if((a[i+1]=='a'||a[i+1]=='A')&&(a[i+2]=='n'||a[i+2]=='N')&&a[i+3]=='(')
{
i=i+4;
int left=1,right=0;
double value;
// char *temp=(char *)calloc(Size,sizeof(char));
// char *temp1=(char *)calloc(Size,sizeof(char));
for(int j=0;j<Size;j++)
{
if(a[i]=='(')
left++;
else if(a[i]==')')
right++;
if(right==left)
break;
temp[j]=a[i++];
}
temp[j++]='@';
temp[j]='\0';
if(j>=Size)
{
Error1=-2;
printf("Error1:int the tan insides is too long!\n");
return -1;
}
value=change(temp,temp1);
reval=tan(value);
}
else
{
Error1=-1;
printf("Error1:no sign like this:%c%c%c!\n",a[i],a[i+1],a[2]);
return -1;
}
}
else
{
Error1=4;
printf("Error1:some sign like %c can't be recognized!\n",a[i]);
return -1;
}
}
reval/=pow(10,power);
if(sign)
reval=-reval;
free(temp);
free(temp1);
return reval;
};
/*功能说明:用来判别字符的类型
参数说明:传入要判断的字符
返回类型:返回字符的类型(自己定义)int类型
*/
int judge2(char ch)
{
if(ch=='.')
return 1;
else if(ch>='0'&&ch<='9')
return 2;
else if(ch=='s'||ch=='S')
return 3;
else if(ch=='c'||ch=='C')
return 4;
else if(ch=='t'||ch=='T')
return 5;
else return 6;
}
/*功能说明:表达式的计算,实现主要的功能
参数说明:s1 原始表达式字符串,s2 临时字符数组,用来保存后序表达式
返回类型:返回表达式的值 double类型
*/
double change(char* s1, char* s2)
{
Stack <char> p;
Stack <double>data1;
Stack <double>data2;
p.push('@');//做标记
double result=-1;
int i=0,j=0;
int left,right;
int n=strlen(s1);
s2=(char*)malloc(sizeof(char)*n);
char* temp=(char *)malloc(sizeof(char)*Size);
int m=0;
double value;
char ch=s1[i];
//......将中序表达式化成后序表达式.......
if(ch=='-')
{
m=0;
temp[m++]=ch;
left=right=0;
while(true)
{
ch=s1[++i];
if(left==right&&(ch=='*'||ch=='/'||ch=='+'||ch=='-'))
break;
else
temp[m++]=ch;
}
temp[m]='\0';
value=compute1(temp);
s2[j++]='#';
data1.push(value);
}
while(i<n-1)
{
if(ch==' ')//忽略空格
ch=s1[++i];
else if(ch=='(')//如果是左括号
{
if(s1[i+1]=='-')
{
left=1;
right=0;
while(left>right)
{
ch=s1[++i];
if(ch=='(')
left++;
else if(ch==')')
right++;
temp[m++]=ch;
}
temp[m-1]='\0';
value=compute1(temp);
data1.push(value);
s2[j++]='#';
}
else
{
p.push(ch);//压栈
ch=s1[++i];//继续向后
}
}
else if(ch==')')//如果是右括号
{
while(p.topvalue()!='(')
s2[j++]=p.pop();//把左括号之前的全弹出并加入到后序数组中
p.pop();
ch=s1[++i];
}
else if(ch=='+'||ch=='-'||ch=='*'||ch=='/')//如果是运算符
{
char w=p.topvalue();
while(precedent(w)>=precedent(ch))//判断符号的优先级
{//如果比栈顶元素的优先级高
s2[j++]=w;//把栈顶弹出并加入后序数组
p.pop();
w=p.topvalue();
}
p.push(ch);
ch=s1[++i];
}
else
{//如果是是操作数
m=0;
temp[m++]=ch;
if(ch<='9'&&ch>='0')
{
while(true)
{
ch=s1[++i];
if(ch==' ')
i++;
else if((ch<='9'&&ch>='0')||ch=='.')
{
temp[m++]=ch;
}
else
break;
}
}
else
{
left=right=0;
while(true)
{
if(ch=='(')left++;
else if(ch==')')right++;
ch=s1[++i];
if(left==right&&left>0)
break;
temp[m++]=ch;
}
}
temp[m]='\0';
printf(".................%s\n",temp);
value=compute1(temp);
data1.push(value);
s2[j++]='#';//直接加入后序数组
}
}
ch=p.pop();
while(ch!='@')//把栈内剩余的运算符都弹出并加入后序数组
{
if(ch=='(')
{
return -1;
}
else
{
s2[j++]=ch;
ch=p.pop();
}
}
s2[j]='\0';
while(!data1.isempty())
{
data2.push(data1.pop());
}
//......中序表达式计算.......
{
double op1,op2;
p.clean();
data1.clean();
int k=0;
for(k=j-1;k>=0;k--)
p.push(s2[k]);
while(!p.isempty())
{
ch=p.pop();
if(ch=='#')
data1.push(data2.pop());
else
{
op1=data1.pop();
op2=data1.pop();
switch (ch)
{
case '+': result=op1+op2;break;
case '-': result=op2-op1;break;
case '*': result=op1*op2;break;
case '/': {
if(op1==0)
{
printf("Error:the divident shouldn't be 0\n");
Error1=-1;
return -1;
}
else
result=op2/op1;
break;
}
default: printf("Error:not the recognized operator %c\n",ch);
}
data1.push(result);
}
}
}
return result;
};
/*功能说明:判断操作符号的优先级别
参数说明:操作符号字符
返回值:优先级别 int
*/
int precedent(char op)
{
switch(op)
{
case '+':
case '-':return 1;
case '*':
case '/':return 2;
default:return 0;
}
};
void main()//测试
{
double result;
char exp[200];
char exp1[200];
char ch;
for(int m=0;m<20;m++)
{
printf("input the expression:");
for(int i=0;i<200;i++)
{
ch=getchar();
if(ch=='\n')
break;
else
exp[i]=ch;
}
exp[i++]='@';
exp[i]='\0';
result=change(exp,exp1);
if(Error1<0)
printf("Error occurs! no rusult,please check......\n");
else
printf("the result is %f :\n",result);
}
}
[/code:1] |
|