수식 문자열 평가
제목 설명
문자열 str이 주어지면 str은 수식을 나타내며 수식에는 정수, 더하기, 빼기, 곱하기, 나누기, 왼쪽 및 오른쪽 괄호가있을 수 있으며 수식의 계산 결과를 반환 할 수 있습니다 (참고 : 제목의 모든 작업은 정수 작업, 반 내림 및 보장됨). 데이터는 합법적이며 0으로 나누지 않습니다.)
설명 입력 :
str (1 ≤ lengthstr ≤ 1000) str (1 \ leq length_ {str} \ leq 1000)을 나타내는 문자열 라인을 출력합니다.s t r ( 1≤l e n g t hS t R≤1 0 0 0 ) (str 계산 결과가 0, int 오버플로 등으로 나뉘 지 않도록합니다.)
출력 설명 :
식의 계산 결과를 나타내는 정수를 출력합니다.
예 1
시작하다
48*((70-65)-43)+8*1
산출
-1816
예 2
시작하다
3+1*4
산출
7
대답:
식 평가는 일반적으로 중위 식을 접미 식으로 변환 한 다음 접미 식에서 두 스택을 사용합니다. 하나는 연산자를 저장하고 다른 하나는 숫자를 저장 한 다음 앞에서 뒤로 계산합니다.
이 문제는 또한 그렇게 할 수 있습니다. 접미사 식의 접미사 프로세스에서 우선 순위에 유의해야합니다. 여기서 "("가장 낮은 우선 순위, 더하기 및 빼기 연산자가 뒤 따르는 가장 높은 우선 순위는 곱하기 및 나누기 연산자.
참고 :이 질문에는 음수가 있으며 '-'연산자를 만났을 때 판단해야합니다.
암호:
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1010;
char s[N];
int nums[N];
char ops[N];
int k1, k2;
int grade( char op ) {
if (op == '(') return 1;
if (op == '+' || op == '-') return 2;
if (op == '*' || op == '/') return 3;
return 0;
}
void calc( char op ) {
int y = nums[ k1-- ];
int x = nums[ k1-- ];
int z;
if ( op == '+') z = x + y;
else if ( op == '-' ) z = x - y;
else if ( op == '*' ) z = x * y;
else z = x / y;
nums[ ++k1 ] = z;
}
int solve() {
k1 = k2 = -1;
int top = 0, val = 0;
for (int i = 0; s[i]; ++i) {
if ( s[i] >= '0' && s[i] <= '9' ) {
val = val * 10 + (s[i] & 15);
if ( s[ i+1 ] >= '0' && s[ i+1 ] <= '9' ) continue;
nums[ ++k1 ] = val;
val = 0;
}
else if ( s[i] == '(' ) ops[ ++k2 ] = s[i];
else if ( s[i] == ')' ) {
while ( ops[k2] != '(' ) calc( ops[ k2-- ] );
k2--;
}
else {
if ( s[i] == '-' ) {
if ( i == 0 || s[ i-1 ] == '(' ) {
val = 0, ++i;
while ( s[i] >= '0' && s[i] <= '9' )
val = val * 10 + (s[ i++ ] & 15);
nums[ ++k1 ] = -val;
val = 0, --i;
continue;
}
}
while ( k2 >= 0 && grade( ops[k2] ) >= grade( s[i] ) )
calc( ops[ k2-- ] );
ops[ ++k2 ] = s[i];
}
}
while ( k2 >= 0 ) calc( ops[ k2-- ] );
return nums[0];
}
int main( void )
{
scanf("%s", s);
printf("%d\n", solve());
return 0;
}