스텍을 이용하여 중위연산에서 후위연산으로 변환하는...(이해를 잘 못하겟네요 ;)
글쓴이: leekukheon / 작성시간: 수, 2009/04/08 - 10:32오전
복학 준비하면서 공부를 하고 있는데요 c로쓴 자료구조라는 책을 보면서 공부하고 있습니다
그런데 스텍 중위연산 후위연산 개념은 이해가 되는데 소스가 잘 이해가 안되네요 ㅠㅠ
여유가 괜찮으시다면 보충설명(주석) 좀 부탁드릴게요....
공부하다가 막히니 흐름도 끊켜서 인터넷하게되네요 ㅠ
=============================================================================
#include <stdio.h> #include <string.h> #include <stdlib.h> typedef enum { lparen, rparen, plus, minus, times, divide, mod, eos, operand } precedence ; typedef precedence element; #define MAX_STACK_SIZE 100 /* 최대 스택 크기 */ precedence stack[MAX_STACK_SIZE]; int top = -1; /* isp와 icp 배열 -- 인덱스는 연산자 lparen, rparen, plus, minus, times, divide, mod, eos의 우선순위 값 */ static int isp[] = { 0, 19, 12, 12, 13, 13, 13, 0 }; static int icp[] = { 20, 19, 12, 12, 13, 13, 13, 0 }; char expr[100]; precedence get_token (char *symbol, int * n); void postfix(void); int eval(void); int main(void) { printf("Enter The Infix String : "); scanf("%s", expr); postfix(); printf ("Postfix String :%d\n", eval()); return 0; } void addS(int *top, element item); element deleteS(int *top); int eval(void) { /* 전역 변수로 되어 있는 후위 표기식 expr을 연산한다 */ precedence token; char symbol; int op1, op2; int n = 0; /* 수식 문자열을 위한 카운터 */ int top = -1; token = get_token(&symbol, &n); while (token != eos) { if (token == operand) addS(&top, symbol - '0'); /* 스택 삽입 */ else { /* 두 피연산자를 삭제하여 연산을 수행한 후, 그 결과를 스택에 삽입함 */ op2 = deleteS(&top); op1 = deleteS(&top); /* 스택 삭제 */ switch (token) { case plus: addS(&top, op1 + op2); break; case minus: addS(&top, op1 - op2); break; case times: addS(&top, op1 * op2); break; case divide:addS(&top, op1 / op2); break; case mod: addS(&top, op1 % op2); break; } } token = get_token(&symbol, &n); } return deleteS(&top); } precedence get_token (char *symbol, int * n) { /* 다음 토큰을 취한다. symbol은 문자 표현이며, token은 그것의 열거된 값으로 표현되고, 명칭으로 반환된다. */ *symbol = expr[(*n)++]; // printf("%c", *symbol); switch (*symbol) { case '(' : return lparen; case ')' : return rparen; case '+' : return plus; case '-' : return minus; case '/' : return divide; case '*' : return times; case '%' : return mod; case '\0' : return eos; default : return operand; } } // 변환 부분 void print_token(precedence token); char post_expr[100]; void postfix(void) { char symbol; precedence token; int n = 0; int top = 0; stack[0] = eos; /* eos를 스택에 놓는다 */ for (token = get_token(&symbol, &n); token != eos; token = get_token(&symbol, &n)) { //putchar(symbol); if (token == operand) print_token(symbol); else if (token == rparen) { /* 왼쪽 괄호가 나올 때까지 토큰들을 제거해서 출력 */ while (stack[top] != lparen) print_token(deleteS(&top)); deleteS(&top); /* 좌괄호를 버린다 */ } else { /* symbol의 isp가 token의 icp보다 크거나 같으면 symbol을 제거하고 출력 */ while (isp[stack[top]] >= icp[token]) print_token(deleteS(&top)); addS(&top, token); } } while ((token = deleteS(&top)) != eos) print_token(token); print_token(eos); strcpy(expr, post_expr); puts(expr); } void print_token(precedence token) { static int index = 0; char aChar; switch (token) { case plus : aChar = '+'; break; case minus : aChar = '-'; break; case divide : aChar = '/'; break; case times : aChar = '*'; break; case mod : aChar = '%'; break; case eos : aChar = '\0'; break; default : aChar = token; } post_expr[index++] = aChar; } void stack_full(); void addS(int *top, element item) { /* 전역 스택에 item을 삽입 */ if (*top >= MAX_STACK_SIZE - 1) { stack_full(); return; } stack[++*top] = item; } element stack_empty(); element deleteS(int *top) { /* stack의 최상위 원소를 반환 */ if (*top == -1) return stack_empty(); return stack[(*top)--]; } void stack_full() { exit (1); } element stack_empty() { exit (1); }
=================================================================================
Forums:
코드 태그를 이용하시면 가독성이 좋아집니다.
1) 아래와 같이 코드 태그를 이용하시면 가독성이 좋아집니다.
2) 요청하신 주석은 달아놓지 않았습니다만(원본 그대로 다시올린겁니다.)
이미 주석은 대충 달려 있는것 같습니다.
어느부분이 이해가 안되는건지 구체적으로 얘기해 주시면 여러분들이 나서서 도움을 주실껍니다.
댓글 달기