expression evaluation (2) | c++ | stack

1. Topic description

Problem Description

  Infix expressions with variables are common mathematical expressions. If the specified variable is composed of no more than 8 lowercase letters; end is a reserved word, indicating the end of the program segment; use? Indicates that the value of the specified variable is output, and a more complex expression (that is, a sequence of statements that can be executed sequentially) can be designed. For example, if you have the following statement:

abc=10
def=8
c=abc+def
abc=abc+5-c*2
? c
? abc
end

Then the output is:

c=18
abc=-21

Note: In order to simplify the programming implementation, the only operators are +, -, *, /, % and ^ (exponential operation), and parentheses () can be processed, and the input arithmetic expression is assumed to be correct.

Requirements: Implemented using a stack structure.

input: sequence of expressions

Output: the value of all specified variables

All evaluations in expressions evaluate to integers. If the divisor is 0 during the calculation, output: Divide 0.

Special case description:
In the expression, if the operand has a negative number (such as -8), special attention should be paid. For example:
10 plus -8 is expressed as: 10+-8.
10 minus -8 is expressed as: 10--8.

 

test input expected output time limit memory limit extra process
Test case 1 display as text
  1. abc=10↵
  2. def=8↵
  3. c=abc+def↵
  4. abc=abc+5-c*2↵
  5. ? c↵
  6. ? abc↵
  7. end↵
display as text
  1. c=18↵
  2. abc=-21↵
1 second 64M 0
Test case 2 display as text
  1. a=12↵
  2. b=5↵
  3. c=a/b↵
  4. d=(a+1)%(b+1)↵
  5. e=a^2↵
  6. f=-12+a↵
  7. g=(a+5)*d-c↵
  8. ? c↵
  9. ? d↵
  10. ? e↵
  11. ? f↵
  12. ? g↵
  13. a=a+10↵
  14. ? a↵
  15. end↵
display as text
  1. c=2↵
  2. d=1↵
  3. e=144↵
  4. f=0↵
  5. g=15↵
  6. a=22↵
1 second 64M 0
Test case 3 display as text
  1. abc=3↵
  2. ab=2^(abc-1)^(5-abc)↵
  3. ? ab↵
  4. end↵
display as text
  1. ab=16↵
1 second 64M 0
Test case 4 display as text
  1. a=2↵
  2. b=a^(a+1)^(10-8)↵
  3. ? b↵
  4. end↵
display as text
  1. b=512↵
1 second 64M 0
Test case 5 display as text
  1. a=10↵
  2. ? a↵
  3. b=-10+10↵
  4. ? b↵
  5. a=-10-10↵
  6. ? a↵
  7. c=a+-10+-10↵
  8. ? c↵
  9. d=-20+-8-8↵
  10. ? d↵
  11. e=a-12*-2↵
  12. ? e↵
  13. f=80--10+2↵
  14. ? f↵
  15. g=-10--10↵
  16. ? g↵
  17. h=-10+-10↵
  18. ? h↵
  19. i=(90)↵
  20. ? i↵
  21. k=(-100)↵
  22. ? k↵
  23. end↵
display as text
  1. a=10↵
  2. b=0↵
  3. a=-20↵
  4. c=-40↵
  5. d=-36↵
  6. e=4↵
  7. f=92↵
  8. g=0↵
  9. h=-20↵
  10. i=90↵
  11. k=-100↵
1 second 64M 0
Test case 6 display as text
  1. abcdefgh=4↵
  2. ten=10↵
  3. a=18-32↵
  4. ? a↵
  5. b=18/abcdefgh↵
  6. ? b↵
  7. c=18%(b-1)↵
  8. ? c↵
  9. d=ten+(ten+ten)*abcdefgh↵
  10. ? d↵
  11. e=ten-2*ten/abcdefgh↵
  12. ? e↵
  13. f=(18-3)*3↵
  14. ? f↵
  15. ten=ten*(ten)↵
  16. ? ten↵
  17. ten=ten/10↵
  18. ten=(ten+2)/(8-ten)↵
  19. ? ten↵
  20. h=(2*3)/(5*2)↵
  21. ? h↵
  22. ten=10↵
  23. x=ten-(80-30)/3*3+abcdefgh↵
  24. y=(((2+8)*2-(2+abcdefgh)/2)*2-8)*2↵
  25. z=(((8+2)*(abcdefgh/2)))↵
  26. ? x↵
  27. ? y↵
  28. ? z↵
  29. end↵
display as text
  1. a=-14↵
  2. b=4↵
  3. c=0↵
  4. d=90↵
  5. e=5↵
  6. f=45↵
  7. ten=100↵
  8. ten=-6↵
  9. h=0↵
  10. x=-34↵
  11. y=52↵
  12. z=20↵
1 second 64M 0

2. Thinking Tips

1. Start with input

The input consists of several lines, which can be divided into the following three types:

①Conventional assignment formula or four arithmetic operations with equal sign

②Beginning with a question mark represents the value of the variable that needs to be output

③end

2. About variables

Consider using a struct for storage.

#define N 110
typedef struct {
	string name;
	int value;
} VRBL;
VRBL v[N];

        Declare that VRBL is a structure. Each v represents a variable, v.name is the name of the variable, and v.value is the current value of the variable.

Still use string, which is very convenient, really clean and hygienic.

3. About the four operations

It's still a stack, and I have done a lot of topics, so I won't repeat them here.

3. Complete code

Although this topic is optional, it is really not difficult in terms of difficulty.

#include<bits/stdc++.h> 
using namespace std;
#define N 110
typedef struct {
	string name;    //name是变量的名字,例如abc,e等。
	int value;      //value是变量的值。
} VRBL;
VRBL v[N];

//若返回值大于1,表示运算符;若返回1,表示是数字;若返回0,表示既不是运算符也不是数字,也就是字母。注意,这里面是不考虑等于号的。
int valu(char c) {
	if ( c==')' )					  return 6;
	if ( c=='^' ) 					  return 5;
	if ( c=='*' || c=='/' || c=='%' ) return 4; 
	if ( c=='+' || c=='-' ) 		  return 3;
	if ( c=='(' ) 					  return 2;
	if ( c>='0' && c<='9' )			  return 1;
									  return 0; 
}

//两个数之间的计算
void cal(int *a1, int a2, char op) {
	switch (op){
		case '+': (*a1) = (*a1) + a2; break;
		case '-': (*a1) = (*a1) - a2; break;
		case '*': (*a1) = (*a1) * a2; break;
		case '/': (*a1) = (*a1) / a2; break;
		case '%': (*a1) = (*a1) % a2; break;
		case '^': (*a1) = pow((*a1),a2); break;
	}
}

int main(){
	
	int valu(char);
	void cal(int*, int ,char);
	
	string Formula;
	int n=0;	//n用来统计变量的个数 
	while (cin>>Formula,Formula!="end") {
		
        //如果是问号
		if (Formula.find('?')!=-1) {
			
			cin >> Formula;
			//遍历一次v,找到相应的变量
			int i;
			for (i=0;i<=n;i++) {
				if (Formula==v[i].name) {
					break;
				}
			}
			cout << v[i].name << '=' << v[i].value << endl;
		}
		
		else {
			//执行通常的赋值或计算
			int target, digit=0; //digit用来遍历Formula,target是待赋值的变量 
			string tpry;         //tpry用来暂时存放读入的字符串内容 
			
			//找到待赋值的变量 
			while (Formula[digit]!='=') {
				tpry+=Formula[digit];
				digit++;
			} digit++;
			
			//将待赋值的变量在v中进行匹配,如果已经有了就直接套用,否则就加入新的 
			if (n==0) {
				target = 0;
				v[0].name = tpry;
				n++;
			}
			else {
				int flag=0;
				for (int i=0;i<n;i++) {
					if (tpry==v[i].name) {
						flag=1;
						target = i;
						break;
					}
				} 
				if (flag==0) {
					target = n;
					v[n].name = tpry;
					n++;
				}
			}
			
			//计算等号后面的内容
			stack<int> Svalue;	//Svalue用来存储值 
			stack<char> Sop;	//Sop用来存储运算符 
			
			int len = Formula.length(), start=digit, flag=1; //flag用来标记正负数
			while ( digit<len ) {
				
				if ( valu( Formula[digit] )==1 )
				//数字 
				{ 
					int cnt=0;
					while ( digit<len && valu(Formula[digit])==1 ) {
						cnt = cnt * 10 + Formula[digit] - '0';
						digit++;
					}
					Svalue.push(cnt*flag);
					flag=1;
				}
				
				else if ( valu( Formula[digit] )>1 )
				//运算符
				{
					if ( Sop.size()==0 ) {
						if (digit==start && Formula[digit]=='-') flag = -1;
						else Sop.push( Formula[digit] );	
					}
					else {
						//Sop不为空
						//负数 
						if ( digit>start && Formula[digit]=='-' && valu(Formula[digit-1])>1 ) {
							flag=-1;
						}
						
						//左括号 
						else if (Formula[digit]=='(' ) {
							Sop.push( Formula[digit] ); 
						}
						
						//右括号
						else if (Formula[digit]==')' ) {
							while ( Sop.size() && Sop.top()!='(' ) {								
								char c = Sop.top();	Sop.pop();
								int a = Svalue.top(); Svalue.pop();
								cal(&Svalue.top(), a, c);
							} 
							Sop.pop();
						}
						
						else {
                            //连续乘方
							if ( Sop.size() && Formula[digit]=='^' && Sop.top()=='^' ) {
								Sop.push('^');
							}
							else {
								if ( Sop.size() && valu(Formula[digit])<=valu(Sop.top()) ) {
									while ( Sop.size() && valu(Formula[digit])<=valu(Sop.top()) ) {
										char c = Sop.top();	Sop.pop();
										int a = Svalue.top(); Svalue.pop();
										cal(&Svalue.top(), a, c);
									}
									Sop.push(Formula[digit]);
								}
								else {
									Sop.push(Formula[digit]);
								}
								
							}
						}	
										 
					}
					digit++;
				}
				
				else if ( valu( Formula[digit] )==0 )
				//字母 
				{
					//找到完整的变量名称
					string word;
					while ( digit<len && valu(Formula[digit])==0 ) {
						word += Formula[digit];
						digit++;
					}
					//匹配并且取值,将其值存入栈
					for (int i=0;i<n;i++) {
						if (v[i].name==word) {
							Svalue.push(v[i].value*flag);
							flag=1;
							break;
						}
					}
				}	
			}

			//补刀
			while ( Sop.size() ) {
				int a = Svalue.top(); Svalue.pop();
				cal(&Svalue.top(), a, Sop.top());
				Sop.pop();
			}
			
			//为目标变量赋新值
			v[target].value = Svalue.top(); 
			
		}
	}
	
	return 0;
}

Guess you like

Origin blog.csdn.net/m0_70241024/article/details/127093358