题意:给出一个C表达式,计算其值。其中操作数只有26个字母,从a到z依次初始值为1到26;操作符有二位的 + 和二位的 - ,和正常意思一样,然后还有一位的自增 ++ 和一位的自减 - - ,都有前缀和后缀两种,都和正常理解的一样。然后计算表达式值,并给出式子中的各变量最后的值。对了,每个变量在表达式中最多只出现一次。
思路:题目最后也有给出思路,就是将所有一位操作符即自增和自减操作符去掉,再将有前缀操作符的变量自增或自减了,然后计算表达式的值,最后将有后缀操作符的变量自增或自减。这里只要在输入串中查找自增和自减操作符就行了,遇到的是前缀的就直接修改相应变量值,遇到后缀的进行标记下。由于题目没有提到空格的情况,开始用gets输入,结果WA了,说明自增或自减操作符自己中间可能有空格,然后自增或自减操作符与修饰的那个变量之间可能有空格。(可能是前者,可能后者,也可能两者都有)所以直接getchar过滤掉空格。但又要原样输入表达式,只好另存了一下。
注意:空格的情况。多处都有可能有空格。
吐槽:这题好像也挺简单的哈,但是在白书的那个专题里,8道题目中这道UVa通过率好像最低,还以为多难的~~~~唉,数据不可信~~不可吓自己~~
晚上还是要及时睡觉啊~就算偶尔看个精彩的比赛到一两点,结束后就睡了吧,别破罐子破摔,搞到四五点再睡的话,休息到十二点也休息不过来了啊~~ 睡不好,干什么都不行,什么都不相干,甚至连电影都懒得看,生活就会变糟~
Code:
#include<stdio.h> #include<string.h> #define MAXN 120 char exp[MAXN]; char ysexp[MAXN]; int zm[30]; int hz[30]; bool flag[30]; int main() { //while(fgets(exp,MAXN-1,stdin)!=NULL) //while(gets(exp)!=NULL) char ch; while((ch=getchar())!=EOF) { int cnt=0; int yscnt=0; do { ysexp[yscnt++]=ch; if(ch!=' ') exp[cnt++]=ch; }while((ch=getchar())!='\n'); ysexp[yscnt]='\0'; exp[cnt]='\0'; printf("Expression: %s\n",ysexp); for(int i=0;i<26;++i) { zm[i]=i+1; hz[i]=0; flag[i]=0;} char *s=exp; while((s=strstr(s,"++"))!=NULL) { if(*(s+2)=='\0' || *(s+2)=='-' || *(s+2)==' ') {//后缀 hz[*(s-1)-'a']++; *s=' '; *(s+1)=' '; } else {//前缀 zm[*(s+2)-'a']++; *s=' '; *(s+1)=' '; } //s++; } s=exp; while((s=strstr(s,"--"))!=NULL) { if(*(s+2)=='\0' || *(s+2)=='+' || *(s+2)==' ') { hz[*(s-1)-'a']--; *s=' '; *(s+1)=' '; } else { zm[*(s+2)-'a']--; *s=' '; *(s+1)=' '; } //s++; } //计算 s=exp; while(*s<'a' || *s>'z') s++;//直到*exp为小写字母 int val=zm[*s-'a']; flag[*s-'a']=1; char c; while((c=*s)!='\0') { if(c=='+') { while(*s<'a' || *s>'z') s++;//直到*exp为小写字母 val+=zm[*s-'a']; flag[*s-'a']=1; } else if(c=='-') { while(*s<'a' || *s>'z') s++; val-=zm[*s-'a']; flag[*s-'a']=1; } s++; } printf(" value = %d\n",val); for(int i=0;i<26;++i) if(flag[i]) { zm[i]+=hz[i]; printf(" %c = %d\n",'a'+i,zm[i]); } } return 0; }
时间: 2024-10-01 08:16:32