게시판 즐겨찾기
편집
드래그 앤 드롭으로
즐겨찾기 아이콘 위치 수정이 가능합니다.
C언어 stack을 이용한 계산기 질문입니다!!
게시물ID : programmer_16645짧은주소 복사하기
작성자 : 우철탄
추천 : 0
조회수 : 3933회
댓글수 : 4개
등록시간 : 2016/04/11 01:27:07
옵션
  • 본인삭제금지
감히 질문드립니다
C언어 자료구조 과제인데
stack을 이용한 계산기 구현입니다. 
stack을 이용해 infix를 postfix로 바꾸어 계산하는 프로그램을 구현하면되는데
+ - / * ^ % 등 대부분 연산자는 구현했으나 unary 연산이 계속 걸립니다 
문자열에서 한글자를 케이스별로 연사자를 분류 하게되는데 단항연사자를 어떻게 구분해야할지 막막하네요 ㅠㅠ 

3-(-3) 이나 3--3 과같은 수식들을 어떻게 구현해야할까요? 

아래는 지금까지 작성한 프로그램입니다.

------------------
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#pragma warning (disable:4996)

char *cStack;
int cSize;
int cTop;

void cInitStack(int aSize)
{
cSize = aSize;
cStack = (char *)malloc(cSize*sizeof(char));
cTop = -1;
}

void cFreeStack()
{
free(cStack);
}

int cPush(char data)
{
if (cTop < cSize - 1) {
cTop++;
cStack[cTop] = data;
return 1;
}
else {
return 0;
}
}

char cPop()
{
if (cTop >= 0) {
return cStack[cTop--];
}
else {
return -1;
}
}

double *dStack;
int dSize;
int dTop;

void dInitStack(int aSize)
{
dSize = aSize;
dStack = (double *)malloc(dSize*sizeof(double));
dTop = -1;
}

void dFreeStack()
{
free(dStack);
}

int dPush(double data)
{
if (dTop < dSize - 1) {
dTop++;
dStack[dTop] = data;
return 1;
}
else {
return 0;
}
}

double dPop()
{
if (dTop >= 0) {
return dStack[dTop--];
}
else {
return -1;
}
}

int GetPriority(int op)
{
switch (op) {
case '(':
return 0;
case '+':
case '-':
return 1;
case '*':
case '/':
case '%':
return 2;
case '^':
return 3;
}
return 100;
}

void MakePostfix(char *postfixExp, const char *infixExp) {
const char *m = infixExp;
char *p = postfixExp, c;
cInitStack(256);

while (*m) {
// 숫자 - 그대로 출력하고 뒤에 공백 하나를 출력한다.
if (isdigit(*m)) {
while (isdigit(*m) || *m == '.') *p++ = *m++;
*p++ = ' ';
}
// 연산자 - 스택에 있는 자기보다 높은 연산자를 모두 꺼내 출력하고 자신은 푸시한다.
else if (strchr("^*/%+-", *m)) {
while (cTop != -1 && GetPriority(cStack[cTop]) >= GetPriority(*m)) {
*p++ = cPop();
}
cPush(*m++);
}
else
// 여는 괄호 - 푸시한다.
if (*m == '(') {
cPush(*m++);
}
// 닫는 괄호 - 여는 괄호가 나올 때까지 팝해서 출력하고 여는 괄호는 버린다.
else if (*m == ')') {
for (;;) {
c = cPop();
if (c == '(') break;
*p++ = c;
}
m++;
}
else {
m++;
}
}
// 스택에 남은 연산자들 모두 꺼낸다.
while (cTop != -1) {
*p++ = cPop();
}
*p = 0;
cFreeStack();
}

double CalcPostfix(const char *postfixExp)
{
const char *p = postfixExp;
double num;
double left, right;

dInitStack(256);
while (*p) {
// 숫자는 스택에 넣는다.
if (isdigit(*p)) {
num = atof(p);
dPush(num);
for (; isdigit(*p) || *p == '.'; p++) { ; }
}
else {
// 연산자는 스택에서 두 수를 꺼내 연산하고 다시 푸시한다.
if (strchr("^*/%+-", *p)) {
right = dPop();
left = dPop();
switch (*p) {
case '+':
dPush(left + right);
break;
case '-':
dPush(left - right);
break;
case '*':
dPush(left*right);
break;
case '/':
if (right == 0.0) {
dPush(0.0);
}
else {
dPush(left / right);
}
break;
case '%':
if (right == 0) {
dPush(0);
}
else {
dPush((int)left % (int)right);
}
break;
case '^':
dPush(pow(left, right));
break;
}
}
// 연산 후 또는 연산자가 아닌 경우 다음 문자로
p++;
}
}
if (dTop != -1) {
num = dPop();
}
else {
num = 0.0;
}
dFreeStack();
return num;
}

int CheckExp(const char *infixExp) {
const char *p;
int count;

for (p = infixExp, count = 0; *p; p++) {
if (*p == '(') count++;
if (*p == ')') count--;
}
return count;
}

int main(void) {
char infixExp[256];
char postfixExp[256];
int Error;
double result;

printf("\n");
printf("\n");
printf("*************************\n");
printf("      STACK 계 산 기\n");
printf("*************************\n");
printf("\n");
printf("\n");
system("pause");
system("cls");
while (1) {
printf("수식 입력(끝내려면, exit 를 입력)\n ->");
gets(infixExp);
if (strcmp(infixExp, "exit") == 0) break;
Error = CheckExp(infixExp);
if (Error != 0) 
printf("수식이 잘못되었습니다.\n");
else {
printf("Infix: %s\n", infixExp);
MakePostfix(postfixExp, infixExp);
result = CalcPostfix(postfixExp);

printf("Postfix: %s\n", postfixExp);
printf("Result: %.2f\n", result);
}
}
}
-------------------------------------
전체 추천리스트 보기
새로운 댓글이 없습니다.
새로운 댓글 확인하기
글쓰기
◀뒤로가기
PC버전
맨위로▲
공지 운영 자료창고 청소년보호