지금 후위계산기 공부하는데 이상하게 내가 쓴 코드에서 * / %가 먼저 계산되는 경우는 오류가 나더라고 다른 경우는 다 잘되는데 한번 봐주라
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdbool.h>
#define MSS 100
typedef char element;
typedef struct
{
element stack[MSS];
int top;
} StackType;
void init(StackType* s) //스택함수 초기화
{
s->top = -1;
}
int is_empty(StackType* s) //공백 상태 확인
{
return(s->top == -1);
}
int is_full(StackType* s) //포화 상태 확인
{
return(s->top == (MSS - 1));
}
void push(StackType* s, element item) //스택삽입
{
if (is_full(s))
{
fprintf(stderr, "스택 포화 에러\n");
return;
}
else s->stack[++(s->top)] = item;
}
element pop(StackType* s) //스택 삭제
{
if (is_empty(s))
{
fprintf(stderr, "스택 공백 에러\n");
exit(1);
}
else return s->stack[(s->top)--];
}
element peek(StackType* s)
{
if (is_empty(s))
{
fprintf(stderr, "스택 공백 에러\n");
exit(1);
}
else return s->stack[s->top];
}
int check_matching(char* in) // 괄호 검사기
{
StackType s;
char ch, open_ch;
int i, n = strlen(in); //문자열의 길이
init(&s); //스택 초기화
for (i = 0; i < n; i++) //문자열의 길이 만큼 반복
{
ch = in[i];
switch (ch)
{
case'(': case'[': case '{': //스택에 괄호 삽입
push(&s, ch);
break;
case')': case']': case'}':
if (is_empty(&s)) return false; // 공백확인
else
{
open_ch = pop(&s);
if ((open_ch == '(' && ch != ')') || (open_ch == '[' && ch != ']') || (open_ch == '{' && ch != '}')) // 괄호의 짝이 맞는지 확인
{
return false;
}
break;
}
}
}
if (!is_empty(&s)) return false; //스택이 남아있으면 오류
return true;
}
int eval(char exp[]) //postfix 계산
{
int op1, op2, value, i = 0;
int len = strlen(exp);
char ch;
StackType s;
init(&s);
for (i = 0; i < len; i++)
{
ch = exp[i];
if (ch != '+' && ch != '-' && ch != '*' && ch != '/' && ch != '%' && ch != '^')
{
value = ch - '0'; //입력이 피연산자
push(&s, value);
}
else //연산자가 들어오면 피연사자를 스택에서 제거
{
op2 = pop(&s);
op1 = pop(&s);
switch (ch)
{
case '+': push(&s, op1 + op2); break;
case '-': push(&s, op1 - op2); break;
case '*': push(&s, op1 * op2); break;
case '/': push(&s, op1 / op2); break;
case '%': push(&s, op1 % op2); break;
case '^': push(&s, pow(op1, op2)); break;
}
}
}
return pop(&s);
}
int prec(char op) //연산자의 우선순위를 반환
{
switch (op)
{
case'(': case')': return 10;
case'+': case'-': return 11;
case'*': case'/': case'%': return 13;
case'^': return 14; // 숫자가 클수록 우선순위가 높다
}
return -1;
}
void ITP(char exp[], char post[])
{
int i = 0, j = 0;
char ch, top_op, cp[MSS]; //post배열을 복사하기위해 cp배열 선언
char test;
int len = strlen(exp);
StackType s;
init(&s);
for (i = 0; i < len; i++)
{
ch = exp[i];
switch (ch)
{
case'+': case'-': case'*': case'^': case'/': case'%':
while (!is_empty(&s) && (prec(ch) <= prec(peek(&s))))
sprintf(post, "%c", pop(&s));
push(&s, ch);
break;
case'(':
push(&s, ch);
break;
case')':
top_op = pop(&s);
while (top_op != '(')
{
sprintf(post, "%c", top_op);
cp[j++] = top_op;
top_op = pop(&s);
}
break;
default:
sprintf(post, "%c", ch);
cp[j++] = ch; //cp배열에 똑같은 문자를 저장후 한칸 올린다.
break;
}
}
while (!is_empty(&s))
{
test = pop(&s);
sprintf(post, "%c", test);
cp[j++] = test;
}
cp[j] = NULL; //cp배열의 0번째 주소에 NULL삽입
strcpy(post, cp); //cp배열을 post배열에 복사
}
void main()
{
int result;
char i[MSS];
char post[MSS];
do
{
scanf("%30s", &i);
if (check_matching(i) == true)
{
ITP(i, post);
result = eval(post);
printf("Postfix : %s\nResult : %d\n\n", post, result);
}
else
printf("Unmatched parentheses\n");
} while (1);
}
댓글 0