Warning: session_start(): open(/tmp/sess_f61488286e4fe0784a0929cb6c2366c0, O_RDWR) failed: No space left on device (28) in /data/wiki/inc/init.php on line 239

Warning: session_start(): Failed to read session data: files (path: ) in /data/wiki/inc/init.php on line 239

Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/inc/auth.php on line 430

Warning: mkdir(): No space left on device in /data/wiki/lib/plugins/dw2pdf/vendor/mpdf/mpdf/src/Cache.php on line 19
Temporary files directory "/data/wiki/data/tmp/dwpdf/324/" is not writable

Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/inc/actions.php on line 38

Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/lib/tpl/dokuwiki/main.php on line 12
2020-2021:teams:no_morning_training:表达式的计算 [CVBB ACM Team]

用户工具

站点工具


2020-2021:teams:no_morning_training:表达式的计算

表达式的计算

给出一个以=结尾的包含+-*/%()的式子,按运算规则计算其值。
挺模板的一个问题
我们一般的数学语言给出的式子是表达式的中缀表达式,而为了计算,我们需要将其转为后缀表达式。

中缀表达式的合法性判定

一般来说给的数据是合法的,但不排除会有题目让你判断是否合法。
这时候我们需要做一个合法性判断。
因为中缀表达式就是我们的自然语言,所以判断起来也比较容易,主要有以下几点:

  1. 开头若有字符,则只能是+或-。
  2. 括号需要匹配,即有“(”必有“)”。

中缀转后缀的方法

用队列存储运算符,栈辅助处理。对每个字符,规则如下:

  1. 若为数字,直接入队(当然,多位数字要提前处理一下)
  2. 若为运算符:
    1. 栈为空直接入栈
    2. 优先级大于栈顶元素入栈
    3. 优先级小于等于栈顶元素,则栈顶元素出栈入队,直到优先级大于栈顶元素。
  3. 若为(,直接入栈
  4. 若为),栈顶元素出栈入队,直到(,两个括号不入队。

计算方法

对于一个后缀表达式,用栈辅助计算
从左至右扫描,若为数字,直接入栈,若为运算符,则将栈顶两个元素计算,计算结果入栈。
直到最后留下一个数字,即为结果。

代码

代码



#include <stdio.h> #include <string.h> #include <stdlib.h> char stack[500]; int queue[500]; void calcu(int r,int top) { switch (stack[top]){

	  case '+':queue[r-1]=queue[r]+queue[r-1];break;
  case '-':queue[r-1]=queue[r-1]-queue[r];break;
  case '*':queue[r-1]=queue[r]*queue[r-1];break;
  case '/':queue[r-1]=queue[r-1]/queue[r];break;
  case '%':queue[r-1]=queue[r-1]%queue[r];break;
  }

} int main() {

      char s[500];
int pr[300]={0};
pr[(int)'+']=pr[(int)'-']=1;
pr[(int)'*']=pr[(int)'/']=pr[(int)'%']=2;
pr[(int)'(']=0;
gets(s);
int top=0,r=0,i=0; 
while (s[i]!='=')
{ 
	  if (s[i]>='0'&&s[i]<='9') 
  {
	  int x=(int)s[i]-48;
	  i++;
	  while (s[i]>='0'&&s[i]<='9') 
	  {
		  x=x*10+(int)s[i]-48;
		  i++;
	  }
	  queue[++r]=x;
	  i--;
  }
  else if (s[i]!='('&&s[i]!=')'&&s[i]!=' '){
	  if (top==0) stack[++top]=s[i];
	  else {
		  if (pr[(int)s[i]]>pr[(int)stack[top]]) stack[++top]=s[i];
		  else {
			  while (top!=0&&pr[(int)s[i]]<=pr[(int)stack[top]]) calcu(r--,top--);
			  stack[++top]=s[i];
		  }
	  }
  }
  else if (s[i]=='(') stack[++top]=s[i];
  else if (s[i]==')') {
		  while (stack[top]!='(') calcu(r--,top--);
		  top--;
  }
  i++;
}
for (int i=top;i>=1;i--) calcu(r--,top--);
printf("%d",queue[1]);
return 0;

} </codedoc>

2020-2021/teams/no_morning_training/表达式的计算.1590914824.txt.gz · 最后更改: 2020/05/31 16:47 由 admin