본문 바로가기

과제모음

[C++]중위게산식의 후위계산식 변환

반응형
▷ 메인부

#include <iostream>
using std::cout;
using std::cin;
using std::endl;
#include <string>
using std::string;
#include "postfix.h"
#include <conio.h> // 화면전환사용
int main(){
string sel; // 선택
Postfix accesspost; // 객체선언
do{
cout << "1. Postfix 2. Exit 3. Clear" << endl;
cout << "---> "
cin >> sel;
if(sel=="2"){ // 2면종료
cout << "Exit Program..." << endl;
break
}
else if(sel=="1"){ // 1이면후위연산실행
accesspost.input(); // 중위식입력
if(!(accesspost.checkpostfix())){ // 입력체크
cout << "Wrong input" << endl; // 잘못된입력
}
else{
accesspost.makepost(); // 후위식변환
cout << "Now access Postfix" << endl;
accesspost.show(); // 후위식출력
cout << "Result : " << accesspost.calc() << endl; // 후위식계산
}
}
else if(sel=="3"){ // 3이면화면전환
system("cls");
}
else{ // 잘못된입력처리
cout << "Wrong select" << endl;
fflush(stdin); // 메모리비움
}
}while(sel!="2"); // 종료선택할때까지반복
return 0;
}

▷ 헤더부 
(Stack.h)
#ifndef _STACK_H_ // 재정의오류방지
#define _STACK_H_

class Stack{
public:
Stack(int len); // 생성자
~Stack(); // 소멸자
void push(int indata); // 스택삽입
int pop(); // 스택출력
bool IsEmpty(); // 스택비었을때
int topval(); // 최상위값반환
private:
int top; // 최상위플래그
int *data; // 스택저장
int size; // 스택크기
};
#endif

(Postfix.h)
#ifndef _POSTFIX_H_ // 재정의오류방지
#define _POSTFIX_H_

#include "Stack.h" // 스택사용위해
#include <string>
using std::string;

class Postfix{
public:
Postfix(); // 생성자
~Postfix(); // 소멸자
void input(); // 중위식입력
void makepost(); // 후위식으로변환
int operand(char *oper, int op1, int op2); // 연산수행
int priority(char op); // 연산자우선순위
void show(); // 출력
int calc(); // 후위식계산
bool isNum(char *ascval); // 숫자여부판단
bool checkpostfix(); // 입력오류판단

private:
string infix; // 중위식입력받는변수
char *postdata; // 후위식저장변수
int len; // 입력된문자열의길이저장
int result; // 계산결과저장
};
#endif




▷ 실행부
(Stack.cpp)
#include "Stack.h"
#include <iostream>
using std::cout;
using std::endl;

Stack::Stack(int len){ // 생성자
top = 0; 
data = new int [len];
// 스택생성(동적할당)
size = len;
}

void Stack::push(int indata){ // 스택입력
if(top == size){ // 풀스택
cout << "Stack is full" << endl;
exit(1); // 종료
}
data[top] = indata; // 전달받은값을스택에저장
top++; // 최상위플래그증가
}

int Stack::pop(){ // 스택출력
int popval; // 출력값저장
if(top==0){ // 빈스택
cout << "Stack is empty now" << endl;
exit(1); // 종료
}
else{ // 스택이비어있지않으면
popval = data[top-1]; // 최상위데이터출력
top--; // 최상위플래그감소
}
return popval; // 출력값반환
}



bool Stack::IsEmpty(){ // 스택이비었는지확인
if(top==0) return true; // 비어있으면참값반환
else return false;
}

int Stack::topval(){ // 최상위값반환
int returnval; // 반환값저장변수
returnval = data[top-1]; // 최상위값을반환
return returnval;

}
Stack::~Stack(){ // 소멸자
delete [] data; // 스택동적할당해제
}

(Postfix.cpp)
#include "postfix.h"
#include "Stack.h"
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

#include <string>
using namespace std;

Postfix::Postfix(){ // 생성자
infix = ' ' // 변수초기화
result = 0;
}

void Postfix::input(){ // 중위식입력
fflush(stdin); // 메모리를먼저비워준다
cout << "Please Input" << endl;
cout << "---> " // 입력대기
getline(cin, infix); // infix 에입력을받는다
len = infix.length(); // 입력문자열의길이저장
}

bool Postfix::checkpostfix(){ // 입력오류판단
bool check=true // T/F 저장변수
if(infix[0] >= '*' && infix[0] <= '/' || infix[0] == '%'){
check = false // 입력의첫번째값이연산자이면오류
}
else if(infix[len-1] >= '*' && infix[len-1] <= '/' || infix[len-1] == '%'){
check = false // 입력의마지막값이숫자가아니면오류
}
else{
for(int i=0; i<len; i++){ // 입력값을모두돌면서
if(infix[i+1] >= '*' && infix[i+1] <= '/' || infix[i+1] == '%'){
if(infix[i] >= '*' && infix[i] <= '/' || infix[i] == '%'){
check = false // 연산자가연속해서올경우에오류
}
}
}
}
return check; // 저장한T/F 반환
}

int Postfix::priority(char op){ // 연산자우선순위(ISP&ICP)
int prinum=0; // 우선순위값반환
switch(op){ // 받아온연산자에따라분기
case'+':
case'-': // +,- 의우선순위는2
prinum = 2;
break;
case'*':
case'/':
case'%': // *,/,% 의우선순위는1
prinum = 1;
break;
case'(': // 여는괄호우선순위3
prinum = 3;
break;
}
return prinum; // 우선순위반환
}

int Postfix::operand(char *oper, int op1, int op2){ // 연산자에따른연산
switch(*oper){ // 전달받아온포인터값oper에따라
    case'+': // +면덧셈
return (op1+op2);
case'-': // -면뺄셈
return (op1-op2);
case'*': // *면곱셈
return (op1*op2);
case'/': // /면나눗셈
return (op1/op2);
case'%': // %면mod연산
return (op1%op2);
default: // 위의연산자가아니면잘못된입력
cout << "Wrong operator" << endl;
exit(1);
}
}

void Postfix::makepost(){ // 후위식변환
int count = 0; // 인덱스
Stack stack(len); // 스택객체생성및크기초기화
postdata = new char [len+1]; // 후위식저장배열동적할당
char asc, oper; // 아스키코드, 연산자저장변수
bool isNum = true // 숫자플래그
for(int i=0; i<len; i++){ // 입력받은크기동안반복
asc = infix[i]; // 아스키변수에문자열파싱하여저장
switch(asc){ // 아스키문자에따라
case'(': // 여는괄호면스택에저장
stack.push(asc);
break;
case '+':
case '-':
case '*':
case '/':
case '%': // 지정된연산자이면
isNum = false // 숫자플래그false
while((priority(stack.topval()) <= priority(asc)) && (!stack.IsEmpty())){
// 빈스택이아니고스택내의데이터가우선권이면
postdata[count] = ' ' // 파싱기중위해whitespace삽입
count++; // 인덱스증가
postdata[count] = stack.pop(); // 최상위스택을후위식배열에저장
count++; // 인덱스증가
}
stack.push(asc); // 지정된값스택에저장
break;
case')': // 닫는괄호
while((oper=stack.pop()) != '('){ // 여는괄호가올때까지oper에스택값반환
postdata[count] = ' ' // 공백삽입후
count++; // 인덱스증가
postdata[count] = oper; // 반환되는스택값들을후위식배열에저장
count++; // 인덱스증가
}
break;
default: 
if(asc >= '0' && asc <= '9'){ // 입력값이숫자이면
if(isNum == false){ // 숫자플래그true로변환
isNum = true
postdata[count] = ' ' // 공백삽입
count++; // 인덱스증가
}
postdata[count] = asc; // 현재숫자값을후위식배열에저장
count++; // 인덱스증가
}
else{ // 그외오류처리
cout << "Wrong Input" << endl;
exit(1); // 종료
}
}
}
while(!stack.IsEmpty()){ // 스택이비어있지않은동안
postdata[count] = ' ' // 후위식배열에공백삽입
count++; // 인덱스증가
postdata[count] = stack.pop(); // 최상위스택을후위식배열에저장
count++; // 인덱스증가
}
postdata[count] = '\0' // char 변환했으므로끝에NULL 문자저장
}

bool Postfix::isNum(char *ascval){ // 숫자여부판단
bool tandf = false // T/F 저장
if(*ascval >= '0' && *ascval <= '9'){
tandf = true //전달값이숫자면true
}
else{ // 그외에false
tandf = false
ascval++;
}
return tandf; // T/F 반환
}

int Postfix::calc(){ // 후위식계산
Stack stack(len); // 스택선언
char *Token; // 토큰
int op1, op2; // 연산대상저장
Token = strtok(postdata, " "); // 하나씩파싱하여검출
while(Token){ // 토큰이면
if(isNum(Token)){ // 토큰이숫자일때
stack.push(atoi(Token)); // 숫자로변환하여스택에저장
}
else{ // 연산자이면
op1 = stack.pop(); // 연산할대상을스택에서뽑아냄
op2 = stack.pop();
stack.push(operand(Token, op2, op1)); // 계산된값을스택에저장
}
Token = strtok(NULL, " ");
}
result = stack.pop(); // 최종결과를result에저장
delete [] Token; // 동적할당해제
return result; // 계산값반환
}

void Postfix::show(){ // 출력
cout << "Infix : " << infix << endl; // 중위식
cout << "Postfix : " << postdata << endl; // 후위식
}
Postfix::~Postfix(){} // 소멸자


09년도 항공대 자료구조 과제입니다.
   
반응형