做了三题表达式的转换题,都是先把中缀表达式转换为后缀表达式,然后再计算。
zjnu1069 表达式的转换——中级
Description
平常我们书写的表达式称为中缀表达式,因为它将运算符放在两个操作数中间,许多情况下为了确定运算顺序,括号是不可少的,而中缀表达式就不必用括号了。 后缀标记法:书写表达式时采用运算紧跟在两个操作数之后,从而实现了无括号处理和优先级处理,使计算机的处理规则简化为:从左到右顺序完成计算,并用结果取而代之。 例如:8-(3+2*6)/5+4可以写为:8 3 2 6*+5/-4+ 其计算步骤为:8 3 2 6 * + 5 / - 4 + 8 3 12 + 5 / - 4 + 8 15 5平常我们书写的表达式称为中缀表达式,因为它将运算符放在两个操作数中间,许多情况下为了确定运算顺序,括号是不可少的,而中缀表达式就不必用括号了。
后缀标记法:书写表达式时采用运算紧跟在两个操作数之后,从而实现了无括号处理和优先级处理,使计算机的处理规则简化为:从左到右顺序完成计算,并用结果取而代之。
例如:8-(3+2*6)/5+4可以写为:8 3 2 6*+5/-4+
其计算步骤为:
8 3 2 6 * + 5 / - 4 +
8 3 12 + 5 / - 4 +
8 15 5 / - 4 +
8 3 - 4 +
5 4 +
9
编写一个程序,完成这个转换,要求输出的每一个数据间都留一个空格。 / - 4 + 8 3 - 4 + 5 4 + 9 编写一个程序,完成这个转换,要求输出的每一个数据间都留一个空格。
Input
就一行,是一个后缀表达式。输入的符号中只有这些基本符号“0123456789+-*/^()”,并且不会出现形如2*-3的格式。
表达式中的基本数字也都是一位的,不会出现形如12形式的数字。
所输入的字符串不要判错。
Output
若干个中缀表达式,第I+1行比第I行少一个运算符和一个操作数,最后一行只有一个数字,表示运算结果。
运算的结果可能为负数,“/”以整除运算。并且中间每一步都不会超过231
Sample Input
(7+8)*9
Sample Output
7 8 + 9 *
15 9 *
135
Hint
还有^运算符的,a^b表示a的b次方
我的做法是先中缀表达式转换为后缀表达式(遇到数字:直接记录下来 ;遇到'(':压栈 ;遇到')':持续出栈,如果出栈的符号不是'('则输出,否则终止出栈。
遇到符号则判断该符号与栈顶符号的运算优先级,如果栈顶符号的运算优先级高或者等于该符号,则出栈并输出,直到遇到左括号或比它优先级高的或栈为空停止并压栈,处理完字符串后将栈中剩余的符号全部输出。 )
接下来就是计算后缀表达式:我们扫一遍记录的后缀表达式即str数组,遇到数字,则把它的值和下标放到set里,遇到符号,则把符号和下标放入队列中,然后每一次找排在队列最前的的符号,在set里面查找比这个符号的下标小且离它最近的两个数字,计算后,把结果放入set,这里这个数的编号可以用符号的编号,这样依次进行,直到set的大小为1,再把最后结果输出。
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<string> #include<bitset> #include<algorithm> using namespace std; typedef long long ll; typedef long double ldb; #define inf 99999999 #define pi acos(-1.0) char s[200]; char q[11111]; char str[200]; struct node{ char c; int index; }q2[11111]; struct node1{ int num,index; }; bool operator<(node1 a,node1 b){ return a.index<b.index; } set<node1>myset; set<node1>::iterator it; int suan(int a,int b,char str) { int i,j; if(str=='+')return a+b; if(str=='-')return a-b; if(str=='*')return a*b; if(str=='/')return a/b; if(str=='^'){ int num=1; for(i=1;i<=b;i++)num*=a; return num; } } int main() { int n,m,i,j,len,front,rear,tot; node1 temp; while(scanf("%s",s+1)!=EOF) { len=strlen(s+1); memset(str,0,sizeof(str)); tot=0; front=1;rear=0; for(i=1;i<=len;i++){ if(s[i]>='0' && s[i]<='9')str[tot++]=s[i]; if(s[i]=='('){ rear++;q[rear]='('; } if(s[i]==')'){ while(front<=rear){ if(q[rear]=='('){ rear--;break; } str[tot++]=q[rear]; rear--; } } if(s[i]=='+' || s[i]=='-'){ while(front<=rear){ if(q[rear]=='(')break; str[tot++]=q[rear]; rear--; } rear++; q[rear]=s[i]; } if(s[i]=='*' || s[i]=='/'){ while(front<=rear){ if(q[rear]=='(' || q[rear]=='+' || q[rear]=='-'){ break; } str[tot++]=q[rear]; rear--; } rear++; q[rear]=s[i]; } if(s[i]=='^'){ while(front<=rear){ if(q[rear]=='(' || q[rear]=='+' || q[rear]=='-' || q[rear]=='*' || q[rear]=='/'){ break; } str[tot++]=q[rear]; rear--; } rear++; q[rear]=s[i]; } } while(front<=rear){ str[tot++]=q[rear]; rear--; } str[tot]='\0'; int flag=1; for(i=0;i<tot;i++){ if(flag)printf("%c",str[i]),flag=0; else printf(" %c",str[i]); } printf("\n"); int front2,rear2; front2=1; rear2=0; myset.clear(); for(i=0;i<tot;i++){ if(str[i]>='0' && str[i]<='9'){ temp.num=str[i]-'0';temp.index=i; myset.insert(temp); } else{ rear2++;q2[rear2].c=str[i];q2[rear2].index=i; } } char c; int index,num1,num2; while(front2<=rear2){ c=q2[front2].c; index=q2[front2].index; front2++; temp.num=1;temp.index=index; it=myset.upper_bound(temp); it--;it--; num1=(*it).num; myset.erase(it++); num2=(*it).num; myset.erase(*it++); temp.num=suan(num1,num2,c); temp.index=index; myset.insert(temp); if(myset.size()==1)break; flag=1; it=myset.begin(); int p=front2; while(1) { if(it==myset.end() && p>rear2)break; if(it==myset.end()){ printf(" %c",q2[p].c); p++;continue; } if((*it).index<q2[p].index ){ if(flag){ flag=0; printf("%d",(*it).num); } else printf(" %d",(*it).num); it++; } else{ printf(" %c",q2[p].c); p++; } } printf("\n"); } it=myset.begin(); cout<<(*it).num<<endl; } return 0; }
Description
按中缀形式输入一个四则运算的表达式,利用算法优选算法把其转换为后缀表达式输出,并求表达式的值。
Input
输入数据有多组 每一组测试数据为带小括号的四则运算中缀表达式,不包含空格。
Output
对于每组测试数据输出两行,第一行四则运算表达式的后缀表达式(每个数字或者操作符之间输出空格,最后一个元素后没有空格),第二行运算结果。 除法操作为整除,比如6/4=1。
Sample Input
8-(3+2*6)/5+4
(7+8)*9
Sample Output
8 3 2 6 * + 5 / - 4 +
9
7 8 + 9 *
135
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<string> #include<bitset> #include<algorithm> using namespace std; typedef long long ll; typedef long double ldb; #define inf 99999999 #define pi acos(-1.0) char s[200]; char q[1111111]; int q1[1111111]; char str[200]; int suan(int a,int b,char str) { int i,j; if(str=='+')return a+b; if(str=='-')return a-b; if(str=='*')return a*b; if(str=='/')return a/b; if(str=='^'){ int num=1; for(i=1;i<=b;i++)num*=a; return num; } } int main() { int n,m,i,j,len,front,rear,tot; while(scanf("%s",s+1)!=EOF) { len=strlen(s+1); memset(str,0,sizeof(str)); tot=0; front=1;rear=0; for(i=1;i<=len;i++){ if(s[i]>='0' && s[i]<='9')str[tot++]=s[i]; //printf("%c ",s[i]); if(s[i]=='('){ rear++;q[rear]='('; } if(s[i]==')'){ while(front<=rear){ if(q[rear]=='('){ rear--;break; } str[tot++]=q[rear]; //printf("%c ",q[rear]); rear--; } } if(s[i]=='+' || s[i]=='-'){ while(front<=rear){ if(q[rear]=='(')break; str[tot++]=q[rear]; //printf("%c ",q[rear]); rear--; } rear++; q[rear]=s[i]; } if(s[i]=='*' || s[i]=='/'){ while(front<=rear){ if(q[rear]=='(' || q[rear]=='+' || q[rear]=='-'){ break; } str[tot++]=q[rear]; //printf("%c ",q[rear]); rear--; } rear++; q[rear]=s[i]; } if(s[i]=='^'){ while(front<=rear){ if(q[rear]=='(' || q[rear]=='+' || q[rear]=='-' || q[rear]=='*' || q[rear]=='/'){ break; } str[tot++]=q[rear]; rear--; } rear++; q[rear]=s[i]; } } while(front<=rear){ str[tot++]=q[rear]; rear--; } str[tot]='\0'; for(i=0;i<tot;i++){ if(i==0)printf("%c",str[i]); else printf(" %c",str[i]); } printf("\n"); front=1;rear=0; int num1,num2; for(i=0;i<tot;i++){ if(str[i]>='0' && str[i]<='9'){ rear++;q1[rear]=str[i]-'0'; } else{ num2=q1[rear]; rear--; num1=q1[rear]; rear--; rear++; q1[rear]=suan(num1,num2,str[i]); } } printf("%d\n",q1[rear]); } return 0; }
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 41 Accepted: 6
Description
A student called Slon is very mischievous in school. He is always bored in class and he is always making a mess. The teacher wanted to calm him down and “tame” him, so he has given him a difficult mathematical problem.
The teacher gives Slon an arithmetic expression A, the integer P and M. Slon has to answer the following question: “What is the minimal non-negative value of variable x in expression A so that the remainder of dividing A with M is equal to P?”. The solution will always exist.
Additionally, it will hold that, if we apply the laws of distribution on expression A, variable x will not multiply variable x (formally, the expression is a polynomial of the first degree in variable x).
Examples of valid expressions A: 5 + x ∗ (3 + 2), x + 3 ∗ x + 4 ∗ (5 + 3 ∗ (2 + x − 2 ∗ x)).
Examples of invalid expressions A: 5 ∗ (3 + x ∗ (3 + x)), x ∗ (x + x ∗ (1 + x))
Input
The first line of input contains the expression A (1 <=|A| <=100 000). The second line of input contains two integers P (0 <= P <= M − 1) i M (1 <= M <= 1 000 000). The arithmetic expression A will only consists of characters +, -, *, (, ), x and digits from 0 to 9. The brackets will always be paired, the operators +, - and * will always be applied to exactly two values (there will not be an expression (-5) or (4+-5)) and all multiplications will be explicit (there will not be an expression 4(5) or 2(x)).
Output
The first and only line of output must contain the minimal non-negative value of variable x.
Sample Input
5+3+x
9 10
20+3+x
0 5
3*(x+(x+4)*5)
1 7
Sample Output
1
2
1
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<string> #include<bitset> #include<algorithm> using namespace std; typedef long long ll; typedef long double ldb; #define inf 1000000007 #define pi acos(-1.0) ll p1,m1; char s[200050]; char q[200050]; char str[200050],str1[200050]; struct node{ char c; int index; }q2[200050]; struct node1{ ll num; int index; }; bool operator<(node1 a,node1 b){ return a.index<b.index; } set<node1>myset; set<node1>::iterator it; ll a[200050]; int cnt; int bianhao[200050]; ll suan(ll a,ll b,char str) { int i,j; if(str=='+')return ((a+b)%m1+m1)%m1; if(str=='-')return ((a-b)%m1+m1)%m1; if(str=='*')return (a*b)%m1; } ll solve(char str1[],int f) { int i,j; node1 temp; int tot=strlen(str1); int front2,rear2; front2=1; rear2=0; myset.clear(); for(i=0;i<tot;i++){ if(str1[i]>='0' && str1[i]<='9'){ if(a[bianhao[i] ]==inf )temp.num=f; else temp.num=a[bianhao[i] ]; temp.index=i; myset.insert(temp); } else{ rear2++;q2[rear2].c=str1[i];q2[rear2].index=i; } } char c; int index,num1,num2; while(front2<=rear2){ c=q2[front2].c; index=q2[front2].index; front2++; temp.num=1;temp.index=index; it=myset.upper_bound(temp); it--;it--; num1=(*it).num; myset.erase(it++); num2=(*it).num; myset.erase(*it); temp.num=suan(num1,num2,c); temp.index=index; myset.insert(temp); if(myset.size()==1)break; } it=myset.begin(); return (*it).num; } int main() { int n,m,i,j,len,front,rear,tot; ll num; node1 temp; while(scanf("%s",s)!=EOF) { scanf("%lld%lld",&p1,&m1); len=strlen(s); memset(str,0,sizeof(str)); tot=0; front=1;rear=0; cnt=0; for(i=0;i<len;i++){ if(s[i]>='0' && s[i]<='9'){ num=s[i]-'0'; for(j=i+1;j<len;j++){ if(s[j]>='0' && s[j]<='9'){ num=(num*10LL+s[j]-'0')%m1; } else break; } str[tot]='0'; a[++cnt]=num; bianhao[tot]=cnt; tot++; i=j-1; } if(s[i]=='x'){ str[tot]='0'; a[++cnt]=inf; bianhao[tot]=cnt; tot++; } if(s[i]=='('){ rear++;q[rear]='('; } if(s[i]==')'){ while(front<=rear){ if(q[rear]=='('){ rear--;break; } str[tot++]=q[rear]; rear--; } } if(s[i]=='+' || s[i]=='-'){ while(front<=rear){ if(q[rear]=='(')break; str[tot++]=q[rear]; rear--; } rear++; q[rear]=s[i]; } if(s[i]=='*'){ while(front<=rear){ if(q[rear]=='(' || q[rear]=='+' || q[rear]=='-'){ break; } str[tot++]=q[rear]; rear--; } rear++; q[rear]=s[i]; } } while(front<=rear){ str[tot++]=q[rear]; rear--; } str[tot]='\0'; strcpy(str1,str); int c=solve(str1,0); strcpy(str1,str); int b=solve(str1,1)-c; for(i=0;i<=m1;i++){ if(( (((ll)b*(ll)i)+(ll)c)%m1+m1)%m1==p1 ){ printf("%d\n",i);break; } } } return 0; }