티스토리 뷰
[소스 코딩]
※ 스택은 이전에 '연결 리스트 기반으로 구현된 스택' 소스를 활용
■ ListBaseStack.h
#ifndef __LB_STACK_H__ #define __LB_STACK_H__ #define TRUE 1 #define FALSE 0 typedef int Data; // 사용자 정의 int형 Data 선언 typedef struct _node // 사용자 정의 구조체 'Node' 정의 { Data data; // 입력 받은 데이터를 저장할 data 선언 struct _node * next; // 다음 노드를 가리킬 노드 포인터 next 선언 } Node; typedef struct _listStack // 사용자 정의 구조체 'ListStack' 정의 { Node * head; // ListStack에 노드 포인터 'head' 선언 } ListStack; typedef ListStack Stack; // ListStack 이름을 'Stack'으로 변경 void StackInit(Stack * pstack); // 스택을 초기화 하는 함수 int SIsEmpty(Stack * pstack); // 스택에 데이터가 비어있는지 확인하는 함수 void SPush(Stack * pstack, Data data); // 스택에 데이터를 삽입하는 함수 Data SPop(Stack * pstack); // 스택에서 데이터를 추출하는 함수 Data SPeek(Stack * pstack); // 스택의 데이터를 확인하는 함수 #endif | cs |
■ ListBaseStack.c
#include <stdio.h> #include <stdlib.h> #include "ListBaseStack.h" // 스택을 초기화 하는 함수 // void StackInit(Stack * pstack) { pstack->head = NULL; } // 스택에 데이터가 비어있는지 확인하는 함수 // int SIsEmpty(Stack * pstack) { if(pstack->head == NULL) return TRUE; else return FALSE; } // 스택에 데이터를 삽입하는 함수 // void SPush(Stack * pstack, Data data) { Node * newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->next = pstack->head; pstack->head = newNode; } // 스택에서 데이터를 추출하는 함수 // Data SPop(Stack * pstack) { Data rdata; Node * rnode; if(SIsEmpty(pstack)) { printf("Stack Memory Error!"); exit(-1); } rdata = pstack->head->data; rnode = pstack->head; pstack->head = pstack->head->next; free(rnode); return rdata; } // 스택의 데이터를 확인하는 함수 // Data SPeek(Stack * pstack) { if(SIsEmpty(pstack)) { printf("Stack Memory Error!"); exit(-1); } return pstack->head->data; } | cs |
■ PostCalculator.h
#ifndef POSTCALCULATOR_H_ #define POSTCALCULATOR_H_ // 후위표기법 수식을 계산하는 함수 // int EvalRPNExp(char exp[]); #endif | cs |
■ PostCalculator.c
#include <string.h> // strlen 함수를 사용하기 위함 #include <ctype.h> // isdigit 함수를 사용하기 위함 #include "ListBaseStack.h" // 후위표기법 수식을 계산하는 함수 // int EvalRPNExp(char exp[]) { Stack stack; int expLen = strlen(exp); int i; char tok, op1, op2; StackInit(&stack); for(i=0; i<expLen; i++) { tok = exp[i]; if(isdigit(tok)) { SPush(&stack, tok - '0'); } else { op2 = SPop(&stack); op1 = SPop(&stack); switch(tok) { case '+': SPush(&stack, op1 + op2); break; case '-': SPush(&stack, op1 - op2); break; case '*': SPush(&stack, op1 * op2); break; case '/': SPush(&stack, op1 / op2); break; } } } return SPop(&stack); } | cs |
■ 사용되는 함수 설명
Stack stack; int expLen = strlen(exp); int i; char tok, op1, op2; StackInit(&stack); | cs |
- Stack 구조체 'stack' 선언
- 'expLen'에 'exp 배열 인자의 길이'만큼 저장
- 변수 i 선언
※ i: 후위표기법으로 저장된 배열의 인덱스 순서
- 변수 tok, op1, op2 선언
※ tok: 후위표기법으로 저장된 배열의 수식을 한 문자씩 임시로 저장하기 위함
※ op1: 계산 시 왼쪽에 배치될 피연산자를 저장할 공간
※ op2: 계산 시 오른쪽에 배치될 피연산자를 저장할 공간
- 스택 생성 및 초기화
for(i=0; i<expLen; i++) { tok = exp[i]; | cs |
--- 후위표기법 계산 반복문 시작 ---
- 'tok'에 exp 배열 i번째 값을 저장
if(isdigit(tok)) { SPush(&stack, tok - '0'); } | cs |
// tok에 저장된 값이 '숫자'일 경우
※ isdigit 함수: 인자 값이 숫자이면 0이 아닌 값을 반환
- 문자형 'tok'를 정수형으로 변환하여 스택에 저장
※ 문자형 숫자에 문자형 '0'을 감산(-)하면 정수형으로 변환
else { op2 = SPop(&stack); op1 = SPop(&stack); switch(tok) { case '+': SPush(&stack, op1 + op2); break; case '-': SPush(&stack, op1 - op2); break; case '*': SPush(&stack, op1 * op2); break; case '/': SPush(&stack, op1 / op2); break; } } | cs |
// tok에 저장된 값이 '문자'일 경우
- 'op2'에 스택에서 꺼낸 피연산자를 저장
※ 먼저 꺼낸 피연산자는 계산 시 연산자 오른쪽에 배치되기 때문에 op2에 저장
- 'op1'에 스택에서 꺼낸 피연산자를 저장
- tok의 종류에 따라 다르게 처리
// '+'일 경우
- 'op1 + op2' 계산 처리 후 결과 값을 스택에 저장 후 switch 종료
// '-'일 경우
- 'op1 - op2' 계산 처리 후 결과 값을 스택에 저장 후 switch 종료
// '*'일 경우
- 'op1 * op2' 계산 처리 후 결과 값을 스택에 저장 후 switch 종료
// '/'일 경우
- 'op1 / op2' 계산 처리 후 결과 값을 스택에 저장 후 switch 종료
--- 후위표기법 계산 반복문 종료 ---
return SPop(&stack); | cs |
- (변환된 수식에 더 이상 처리할 데이터가 없으면) 스택에 저장된 데이터(계산 결과 값)를 꺼내어 반환
■ PostCalculatorMain.c
#include <stdio.h> #include "PostCalculator.h" int main(void) { char postExp1[] = "563/-"; char postExp2[] = "315+*2/"; printf("'%s' → %d \n", postExp1, EvalRPNExp(postExp1)); printf("'%s' → %d \n", postExp2, EvalRPNExp(postExp2)); return 0; } | cs |
※ 후위표기법으로 작성된 수식을 배열에 저장
- 문자형 배열 'postExp1'에 '563/-' 수식을 저장
- 문자형 배열 'postExp2'에 '315+*2/' 수식을 저장
- 각각 계산 처리된 결과 값을 출력
■ 실행결과
'자료구조' 카테고리의 다른 글
[ch 07-1] 큐의 이해와 ADT 정의 (0) | 2016.04.07 |
---|---|
[ch 06-4] 계산기 프로그램 구현_5(최종 통합 구현) (1) | 2016.04.07 |
[ch 06-4] 계산기 프로그램 구현_3(후위표기법 수식 계산 개념) (0) | 2016.04.06 |
[ch 06-4] 계산기 프로그램 구현_2(중위표기법->후위표기법 변환 구현) (3) | 2016.04.06 |
[ch 06-4] 계산기 프로그램 구현_1(전위/중위/후위표기법 개념) (0) | 2016.04.05 |
- Total
- Today
- Yesterday
- 자료구조
- SWT
- 여행영어 100일의 기적
- 응용
- VCL
- RA
- 작문
- SysUtils
- 영어
- 상황
- 일기
- 독해
- Delphi
- 왕초보 영어회화 100일의 기적
- 스택
- 계산기
- 말하기
- wfd
- Pte
- java
- tdataset
- 설명
- 문법
- 대상
- ADODB
- Reference
- System
- 알고리즘
- 정렬
- 교육센터
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |