您的位置:首页 > 其它

波兰式计算器

2011-07-09 10:05 190 查看
 

11.波兰式计算器

成绩: 15 / 折扣: 0.8

背景

以下是几个标准的表达式:
5 * 2 + -3
5 * (2 + -3)
5 + ((-4 * -5) + (((5 + (6 - 2)) * 7 + ((4 + 2) * (3 - 1))))
与之等价的波兰表达式为
+ * 5 2 -3
* 5 + 2 -3
+ 5 + * -4 -5 + * + 5 - 6 2 7 * + 4 2 - 3 1
在普通的表达式中,符号是位于运算对象之间的,而在波兰表达式中,运算符号位于参与运算的对象之前。
波兰式在计算中的价值在于它不需要使用括号,之所以如此是由于波兰式的操作符的先后顺序是明确的。
如果我们用 P 表示波兰表达式,用 O 表示操作符,用 D 表示数字,则可以将波兰表达式定义为 P = O P P 或 P = D。

任务

编写程序计算波兰表达式的值。

输入

输入第一行是一个整数,表示输入文件中共有几个波兰式,之后每一行是一个波兰表达式。
每个表达式包含数字和二元操作符 +、-、*,操作数和运算结果都在 [-101000, 101000] 之间。
可以假设每行的数据(运算符号和数字)总共不超过 100 个。

输出

对每个表达式输出其值。
 #include<stdio.h>
#include<string.h>
int get(char a[],char num[][2005],char s[]);
void rever(char s[]);
void cal(char num[][2005],char s[],int l);
void add(char s1[],char s2[],char num[]);
void mul(char s1[],char s2[],char num[]);
int min(char s1[],char s2[],char num[]);

main()
{ int m,i,j,k,l;
char s[210],a[150000],Num[210][2005];

scanf("%d",&m);
getchar();
for(i=0;i<m;i++)
{ gets(a);
for(k=0;k<210;k++)
for(j=0;j<2005;j++)
{ if(j==0||j==2004)
Num[k][j]='\0';
else
Num[k][j]='0';
}
for(k=0;k<210;k++)
s[k]='\0';
l=get(a,Num,s);
if(l!=1)
{
cal(Num,s,l);
rever(&Num[0][1]);
if(!strcmp(Num[0],"0")||!strcmp(Num[0],"-0"))
{ printf("0\n");
return 0;
}
if(Num[0][0]=='-')
printf("%s\n",Num[0]);
else
printf("%s\n",&Num[0][1]);
}
else
{ if(!strcmp(a,"-0"))
{ printf("0\n");
}
else
{if(a[0]=='-')
printf("%s\n",a);
else
{ if(a[0]>='0'&&a[0]<='9')
printf("%s\n",a);
else
printf("%s\n",&a[1]);
}
}
}
}
}

int get(char a[],char num[][2005],char s[])
{ int j=0,t=0,k=0;
while(a[j]!='\0')
{ t=0;
if(a[j+1]>='0'&&a[j+1]<='9'||a[j]>='0'&&a[j]<='9')
{ for(;;j++)
{ num[k][t++]=a[j];
if(!(a[j+1]>='0'&&a[j+1]<='9'))
break;
}
num[k][t]='\0';
rever(&num[k++][1]);
}
else
{ if(a[j]!=' ')
{ s[k]=a[j];
num[k++][0]='\0';
}
}
j++;
}
return k;
}

void rever(char s[])
{ int k,longth;
char c;
longth=strlen(s);
for(k=0;k<longth/2;k++)
{ c=s[k];
s[k]=s[longth-k-1];
s[longth-k-1]=c;
}
}

void cal(char num[][2005],char s[],int l)
{ int i,k,flag;
for(i=0;i<l;i++)
{ if(num[i][0]!='\0'&&num[i+1][0]!='\0')
{ switch(s[i-1])
{ case '+' : { if(num[i][0]=='-'&&num[i+1][0]!='-')
{ flag=min(&num[i+1][1],&num[i][1],&num[i-1][1]);
if(flag)
num[i-1][0]='-';
else
num[i-1][0]=' ';
}
else
{ if(num[i][0]=='-'&&num[i+1][0]=='-')
{ num[i-1][0]='-';
add(&num[i][1],&num[i+1][1],&num[i-1][1]);
}
else
{ if(num[i][0]!='-'&&num[i+1][0]=='-')
{ flag=min(&num[i][1],&num[i+1][1],&num[i-1][1]);
if(flag)
num[i-1][0]='-';
else
num[i-1][0]=' ';
}
else
{ num[i-1][0]=' ';
add(&num[i][1],&num[i+1][1],&num[i-1][1]);
}
}
}
break;
}
case '-' : { if(num[i][0]!='-'&&num[i+1][0]!='-')
{ flag=min(&num[i][1],&num[i+1][1],&num[i-1][1]);
if(flag)
num[i-1][0]='-';
else
num[i-1][0]=' ';
}
else
{ if(num[i][0]=='-'&&num[i+1][0]!='-')
{ num[i-1][0]='-';
add(&num[i][1],&num[i+1][1],&num[i-1][1]);
}
else
{ if(num[i][0]!='-'&&num[i+1][0]=='-')
{ num[i-1][0]=' ';
add(&num[i][1],&num[i+1][1],&num[i-1][1]);
}
else
{ flag=min(&num[i+1][1],&num[i][1],&num[i-1][1]);
if(flag)
num[i-1][0]='-';
else
num[i-1][0]=' ';
}
}
}
break;
}
case '*' : { if(num[i][0]=='-'&&num[i+1][0]=='-'||num[i][0]!='-'&&num[i+1][0]!='-')
num[i-1][0]=' ';
else
num[i-1][0]='-';
mul(&num[i][1],&num[i+1][1],&num[i-1][1]);
break;
}
}
for(k=i;k<l;k++)
{ s[k]=s[k+2];
strcpy(num[k],num[k+2]);
}
i=0;
l-=2;
}
}
}

void add(char s1[],char s2[],char num[])
{ long int l1,l2,l,i;
for(i=0;i<2005;i++)
num[i]='0';
l1=strlen(s1);
l2=strlen(s2);
if(l1>l2)
l=l1;
else
l=l2;
s1[l1]='0';
s2[l2]='0';
for(i=0;i<l;i++)
{
if(num[i]-'0'+s1[i]-'0'+s2[i]-'0'>9)
{ num[i]=num[i]-'0'+s1[i]-'0'+s2[i]-'0'-10+'0';
num[i+1]+=1;
}
else
num[i]=num[i]-'0'+s1[i]-'0'+s2[i]-'0'+'0';
}
if(num[i]!='0')
{ num[i+1]='\0';}
else
num[i]='\0';
s1[l1]='\0';
s2[l2]='\0';
}

void mul(char a[],char b[],char num[])
{ int i,j,c[2004],l1,l2;
l1=strlen(a);
l2=strlen(b);
for(i=0;i<2004;i++)
{c[i]=0;
num[i]='0'; }
for(i=0;i<l1;i++)
for(j=0;j<l2;j++)
{ c[i+j]+=(a[i]-'0')*(b[j]-'0');
}
for(i=0;i<l1+l2;i++)
{
num[i]=c[i]%10+'0';
c[i+1]+=c[i]/10;
}
while(num[i]=='0'&&i>0)
{ num[i]='\0';
i--;
}
}

int min(char s1[],char s2[],char num[])
{ int i,j,l1,l2,flag,l,lm;
char c1[2004],c2[2004];
for(i=0;i<2004;i++)
{ num[i]='0';
c1[i]='0';
c2[i]='0';
}
l1=strlen(s1);
l2=strlen(s2);
l=l1;
lm=l2;
if(l1!=l2)
{ if(l1<l2)
{flag=1;
l=l2;
lm=l1;
strcpy(c1,s2);
strcpy(c2,s1);
}
else
{flag=0;
strcpy(c1,s1);
strcpy(c2,s2);
}
}
else
{ rever(s1);
rever(s2);
for(j=0;j<l1;j++)
{ if(s1[j]<s2[j])
{ flag=1;
rever(s1);
rever(s2);
strcpy(c1,s2);
strcpy(c2,s1);
l=l2;
lm=l1;
break;
}
}
if(j==l1)
{flag=0;
rever(s1);
rever(s2);
strcpy(c1,s1);
strcpy(c2,s2);
}

}
c1[l]='0';
c2[lm]='0';
for(i=0;i<l;i++)
{ if(num[i]+c1[i]-c2[i]<'0')
{ num[i]=num[i]+c1[i]-c2[i]+10;
num[i+1]-=1;
}
else
{ num[i]+=c1[i]-c2[i];
}
}
while(num[i]=='0'&&i>=1)
num[i--]='\0';
return flag;
}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: