Topic Connection: http://codevs.cn/problem/1107/
A very wonderful topic.
For a class of arithmetic expressions, it is possible to do this in the form of a suffix expression in the compiler principle. The detailed approach is to maintain two stacks, one stack to hold the numbers in the expression, and a stack to hold the operators in the expression, give each operator a priority, we want to maintain the monotony of the stack, each time the operator is read into the number or operator, read into the operator, If this operator has a lower precedence than the operator at the top of the stack, the top element of the stack pops up. The operator of the top of the stack and the top of the stack of two numbers out to do an operation, the results of the calculation into the digital stack. Until the stack top element of the operator stack has a lower precedence than this operator.
Then the topic has a pit point, one is read into the expression string may have a space, so can not directly scanf the read into the data operation. The second is to infer whether the expression is equivalent, the values brought into the hypothesis may not be WA, so in order to avoid such a situation, we should be a decimal number, the three-state function to infer whether the result of the expression is equal, more generations into a few decimal calculation. There is basically no possibility of accidental wa happening.
#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include < algorithm> #include <map> #include <cmath> #define MAXN 1000#define EPS (1e-5) using namespace Std;long long Stackofnum[maxn];int topnum=0; Save the stack of numbers and stack top subscript char stackofsign[maxn];int topsign=0; Save the stack of operational symbols and stack top subscript bool needpop[50][50]; Needpop[i][j]=true indicates that the current operator is I, and that the stack top operator is J requires a stack bool Istrue[30];int dcmp (Long long A,long long B)//a>b return 1; a=b return 0; A<b return-1{if (Fabs (A-B) <=eps) return 0; if (a>b) return 1; return-1;} Long Long cal (Long long A,long long B,char cmd) {switch (cmd) {case ' ^ ': {Long long ans=1; for (int i=1;i<= (int) b;i++) ans*=a; return ans; } case ' + ': return a+b; Case '-': return a-B; Case ' * ': return a*b; Case '/': return a/b; } return 0;} Long Long Getans (char s[],int len,long long A)//to find the value of an expression, len= expressionLength, a= the corresponding value of the letter a {int p=1;//Pointer to the current expression subscript topnum=0; topsign=0; while (P<=len) {while (s[p]== ") p++;if (P>len) break; if (s[p]>= ' 0 ' &&s[p]<= ' 9 ')//is the number {int nownum=0; while (P<=len) {if (!) ( s[p]>= ' 0 ' &&s[p]<= ' 9 ')///Now S[P] is not a number break; nownum*=10; nownum+=s[p]-' 0 '; p++; } Stackofnum[++topnum]=nownum; This number into the stack continue; } else if (s[p]== ' a ') stackofnum[++topnum]=a; Let's say a, pressing a corresponding number into the stack else//s[p] is an operator that will have all of the stack precedence {while (topsign>0&&topnum>0) {if (Needpop[s[p]][stackofsign[topsign]]) {if (stackofsign[topsign]== ') (')//right parenthesis encountered opening parenthesis {topsign--; Break } stackofnum[topnum-1]=cal (Stackofnum[topnum-1],stackofnum[topnum],stackofsign[topsign]); topnum--; topsign--; } else break; } if (s[p]!= ') ') stackofsign[++topsign]=s[p]; } p++; } while (topsign>0&&topnum>1) {stackofnum[topnum-1]=cal (Stackofnum[topnum-1],stackofnum[topnum] , Stackofsign[topsign]); topnum--; topsign--; } return stackofnum[topnum];} int main () {memset (istrue,true,sizeof (isTrue)); Make a big watch first! needpop[' ^ ' [' ^ ']=true; needpop[' ^ ' [' + ']=false; needpop[' ^ ' ['-']=false; needpop[' ^ ' [' * ']=false; needpop[' ^ ' ['/']=false; needpop[' ^ ' [' (']=false; ----------------------needpop[' + ' [' ^ ']=true; needpop[' + ' [' + ']=true; needpop[' + ' ['-']=true; needpop[' + ' [' * ']=true; needpop[' + ' ['/']=true; needpop[' + ' [' (']=false; ----------------------needpop['-' [' ^ ']=true; needpop['-' [' + ']=true; needpop['-' ['-']=trUe needpop['-' [' * ']=true; needpop['-' ['/']=true; needpop['-' [' (']=false; ----------------------needpop[' * ' [' ^ ']=true; needpop[' * ' [' + ']=false; needpop[' * ' ['-']=false; needpop[' * ' [' * ']=true; needpop[' * ' ['/']=true; needpop[' * ' [' (']=false; ----------------------needpop['/' [' ^ ']=true; needpop['/' [' + ']=false; needpop['/' ['-']=false; needpop['/' [' * ']=true; needpop['/' ['/']=true; needpop['/' [' (']=false; ----------------------needpop[' ('] [' ^ ']=false; Needpop[' ('] [' + ']=false; needpop[' (' [') '-']=false; needpop[' (' ['] ' * ']=false; Needpop[' ('] ['/']=false; needpop[' (' [') ' (']=false; ----------------------needpop[') ' [' ^ ']=true; needpop[') ' [' + ']=true; needpop[') ' ['-']=true; needpop[') ' [' * ']=true; needpop[') ' ['/']=true; needpop[') ' [' (']=true; Char S[MAXN]; int n; Long Long trueans1,trueans2,nowans1,nowans2; Trueans= the answer that should be obtained after bringing in a value, nowans= the option to bring in a worth of answer//scanf ("%s", s+1);ETS (S+1); Trueans1=getans (S,strlen (s+1), 1.4); Trueans2=getans (S,strlen (s+1), 2.8); scanf ("%d", &n); gets (s+1); for (int i=0;i<n;i++) {//scanf ("%s", s+1), gets (s+1); Nowans1=getans (S,strlen (s+1), 1.4); Nowans2=getans (S,strlen ( s+1), 2.8); if (dcmp (trueans1,nowans1)!=0)//trueans==nowans Istrue[i]=false; if (dcmp (TRUEANS2,NOWANS2)!=0)//trueans==nowans Istrue[i]=false; } for (int i=0;i<n;i++) if (Istrue[i]) printf ("%c", ' A ' +i); printf ("\ n"); return 0;}
[Codevs 1107] [NOIP 1107] Equivalent expression