做了三题表达式的转换题,都是先把中缀表达式转换为后缀表达式,然后再计算。
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]=' ';
int flag=1;
for(i=0;i<tot;i++){
if(flag)printf("%c",str[i]),flag=0;
else printf(" %c",str[i]);
}
printf("
");
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("
");
}
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]=' ';
for(i=0;i<tot;i++){
if(i==0)printf("%c",str[i]);
else printf(" %c",str[i]);
}
printf("
");
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
",q1[rear]);
}
return 0;
}
zjnu1715 SLON
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]=' ';
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
",i);break;
}
}
}
return 0;
}