UVa 327 计算简单C表达式

题意:给出一个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

UVa 327 计算简单C表达式的相关文章

编译器--简单数学表达式计算器

做了一个能够计算简单数学表达式值的小计算器,算不上是编译器,但用到了编译器的知识.最近在看一些编译器的东西,所以动手写这个最简单的计算器,既是对那些抽象的编译器知识有个形象的认识,也为后面添加复杂的东西--语句打下基础.此计算器是以<编译原理与实践>中实现的tiny编译器为参考写的,tiny是一个值得去研究的编译器,可以说是麻雀虽小,五脏俱全.从词法分析到代码生成都有,并且代码非常清晰易懂.我觉得想要了解编译器,可以从tiny入手,去将它跑起来并分析.废话不多说,开始记录这个小计算器. 先说下

【LeetCode刷题Java版】Evaluate Reverse Polish Notation(计算逆波兰表达式)

Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, *, /. Each operand may be an integer or another expression. Some examples: ["2", "1", "+", "3", "*"] -&g

UVa 725 Division --- 简单枚举

题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=666 /* UVa 725 Division --- 简单枚举 */ #include <cstdio> #include <cstring> bool used[10]; /* 判断传进来的两个数是否满足条件 */ bool judge(int a, i

简单算术表达式的求值程序

题目: 写一个三则运算(加减乘)表达式的求值程序,为了简化,规定数字只有一位,表达式内没有空格,但允许有括号.满足四则运算的结合性和优先级. 解答: 这是一道编译原理题,题目的要求把词法分析简单化了,只做语法分析.一般使用递归下降法求解. 首先写出BNF(包括结合性和优先权). exp → exp addop term | t e r m addop → + | - term → term mulop factor | f a c t o r mulop → * factor → ( exp )

【龙书笔记】用Python实现一个简单数学表达式从中缀到后缀语法的翻译器(采用递归下降分析法)

上篇笔记介绍了语法分析相关的一些基础概念,本篇笔记根据龙书第2.5节的内容实现一个针对简单表达式的后缀式语法翻译器Demo. 备注:原书中的demo是java实例,我给出的将是逻辑一致的Python版本的实现. 在简单后缀翻译器代码实现之前,还需要介绍几个基本概念. 1. 自顶向下分析法(top-down parsing) 顾名思义,top-down分析法的思路是推导产生式时,以产生式开始符号作为root节点,从上至下依次构建其子节点,最终构造出语法分析树.在具体实现时,它会把输入字符串从左到右

简单算术表达式求值

#include <stdio.h> #include <string.h> int main() { int n,i; char a[200]; int f=0,l=0; gets(a); for(i=0;i<strlen(a);i++) { if(a[i]>='0'&&a[i]<='9')//如果是数字 { if(a[i+1]>='0'&&a[i+1]<='9')//如果后面那个也是数字 { f=(f+a[i]-48

uva 327 - Evaluating Simple C Expressions

 Evaluating Simple C Expressions  The task in this problem is to evaluate a sequence of simple C expressions, buy you need not know C to solve the problem! Each of the expressions will appear on a line by itself and will contain no more than 110 char

Java初学者:内建函数计算简单的数学表达式

这个应该在之前写的,忘记了,补上 这次我们说一下如何用java计算数学表达式的值,比如,我们要计算sin(pi/3) + cos(pi/6) + 5.6^3,怎么计算呢?这里我们需要用到java的math的内建函数,所谓内建函数,就是java已经给你的方法,你用就好了,有时候你需要自己导入包,但math却不用,java会自动导入,不用你手动导入.下面我们来看一下这个例子: 编译运行通过,没问题,这个很简单. Math.PI, 就是派了,Math.pow(z, 3),就是计算z的立方,Math.s

简单的表达式计算 c++

1 #include<iostream> 2 #include<stack> 3 #include<string> 4 #include<vector> 5 #include<map> 6 #include<algorithm> 7 using namespace std; 8 9 map<const char, int> priority;//用map来储存运算符的优先级 10 11 int compare(char a