murry2018 / BelarusianCutlet

[벨라루스 전통 돈까스집] 알고리즘 스터디용 리포지토리입니다.
0 stars 0 forks source link

21W20-Stack 2 #7

Open murry2018 opened 3 years ago

murry2018 commented 3 years ago

계산기 코드

SWEA 1222, 1223, 1224 모두 같은 코드로 풀었습니다.

#include <cstdio>
#include <stack>
#include <cctype>
#include <cstring>

using namespace std;

bool exists(char *s, char item) {
  for (int i = 0; s[i] != 0; i++) {
    if (s[i] == item)
      return true;
  }
  return false;
}

// op: operator character
// isp: is this operator in stack?
int precedence(char op, bool in_stack) {
  static char isp[4][3] = {"(", "+-", "*/", ""};
  static char icp[4][3] = {"", "+-", "*/", "("};
  char (*p)[3] = in_stack? isp: icp;
  for (int i = 0; i < 4; i++) {
    if (exists(p[i], op))
      return i;
  }
  return -1;
}

void infix_to_postfix(char *infix, char *out) {
  stack<char> ops;
  int cnt = 0;
  for (int i = 0; infix[i] != 0; i++) {
    if (isdigit(infix[i])) {
      out[cnt++] = infix[i];
    } else if (infix[i] == ')') {
      while (ops.top() != '(') {
        out[cnt++] = ops.top();
        ops.pop();
      }
      ops.pop(); // remove '('
    } else { // infix[i] is operator
      int icp = precedence(infix[i], false);
      while (!ops.empty()) {
        int isp = precedence(ops.top(), true);
        if (isp < icp) {
          break;
        } else {
          out[cnt++] = ops.top();
          ops.pop();
        }
      }
      ops.push(infix[i]);
    }
  }
  while (!ops.empty()) {
    out[cnt++] = ops.top();
    ops.pop();
  }
  out[cnt] = 0;
}

int compute_postfix(char *postfix) {
  int res = 0;
  stack<int> s;
  for (int i = 0; postfix[i] != 0; i++) {
    if (isdigit(postfix[i])) {
      s.push(postfix[i]-'0');
    } else { // if postfix[i] is operator
      int t1, t2;
      t2 = s.top();
      s.pop();
      t1 = s.top();
      s.pop();
      char op = postfix[i];
      switch(op) {
        case '+': s.push(t1+t2); break;
        case '-': s.push(t1-t2); break;
        case '*': s.push(t1*t2); break;
        case '/': s.push(t1/t2); break;
      }
    }
  }
  if (!s.empty())
    res = s.top();
  return res;
}

int main() {
  char infix[10000];
  char postfix[10000];
  for (int i = 0; i < 10; i++) {
    int j, len;
    scanf("%d\n", &len);
    for (j = 0; j < len; j++) {
      infix[j] = getchar();
    }
    infix[j] = 0;
    while (getchar() != '\n');
    infix_to_postfix(infix, postfix);
    int result = compute_postfix(postfix);

    printf("#%d %d\n", i+1, result);
  }
}
moodmine commented 3 years ago

계산기

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include <stdio.h>

using namespace std;

#define MAX_N 200

int top;
int stack[MAX_N];

void stackInit(void)
{
    top = -1;
}

int stackIsEmpty(void)
{
    return (top == -1);
}

int stackIsFull(void)
{
    return (top == MAX_N - 1);
}

int stackPush(int value)
{
    if (stackIsFull())
    {
        printf("stack overflow!");
        return 0;
    }
    top++;
    stack[top] = value;

    return 1;
}

int stackPop(int* value)
{
    if (stackIsEmpty())
    {
        printf("stack is empty!");
        return 0;
    }
    *value = stack[top];
    top--;

    return 1;
}

int main(int argc, char** argv)
{
    int test_case;
    int T;

    //freopen("input.txt", "r", stdin);
    //cin >> T;
    T = 10;
    for (test_case = 1; test_case <= T; ++test_case)
    {
        int num;
        char in[200];
        char post[200] = { 0, };
        stackInit();
        scanf("%d", &num);
        scanf("%s", in);
        int i = 0;
        int j = 0;
        int data;

        while (in[i])
        {
            if (in[i] >= '0' && in[i] <= '9')
            {
                post[j] = in[i];
                j++;
            }
            else
            {
                switch (in[i])
                {
                case '(':
                    stackPush(in[i]);
                    break;

                case '+':
                    if (stack[top] == '+' || stack[top] == '*')
                    {
                        stackPop(&data);
                        post[j] = data;
                        j++;
                    }
                    stackPush(in[i]);
                    break;

                case '*':
                    if (stack[top] == '*')
                    {
                        stackPop(&data);
                        post[j] = data;
                        j++;
                    }
                    stackPush(in[i]);
                    break;

                case ')':
                    while (stack[top] != '(')
                    {
                        stackPop(&data);
                        post[j] = data;
                        j++;
                    }
                    stackPop(&data);
                    break;
                }
            }
            i++;
        }
        while (!stackIsEmpty())
        {
            stackPop(&data);
            post[j] = data;
            j++;
        }

        int result = 0;
        int tmp = 0;
        i = 0;
        while (post[i])
        {
            if (post[i] >= '0' && post[i] <= '9')
            {
                stackPush(post[i] - 48);
            }
            if (post[i] == '+')
            {
                stackPop(&data);
                tmp = data;
                stackPop(&data);
                tmp = tmp + data;
                stackPush(tmp);
            }
            if (post[i] == '*')
            {
                stackPop(&data);
                tmp = data;
                stackPop(&data);
                tmp = tmp * data;
                stackPush(tmp);
            }
            i++;
        }
        printf("#%d %d\n", test_case, stack[top]);
    }
    return 0;
}