이 페이지는 코딩도장 데이터의 읽기 전용 정적 보관본입니다.

이상한 계산기

일반적으로 괄호가 없는 사칙연산을 계산할 때는 왼쪽에서부터 계산하며, 곱하기와 나누기를 더하기와 빼기보다 먼저 계산한다.

괄호가 없는 사칙연산 식을 입력받았을 때 오른쪽에서부터, 더하기나 빼기를 곱하기나 나누기보다 먼저 계산한 결과를 리턴하는 코드를 작성하라.

(단, 사칙연산 식은 문자열의 형식으로 입력받는다)

입력예시:

2+3*12/15-9

출력예시:

10

2018/05/06 20:14

myyh2357

+1 답을 작성하면서 의문이 들었던게 오른쪽에서부터 계산한다는 말이 꼭 필요한지 모르겠습니다. 저는 이게 15-9 를 -6으로 계산하라는 뜻이었나 했는데 보여주신 예시 답을 보면 그것도 아니더군요. 혹시 제가 놓친게 있다면 짚어주시면 감사하겠습니다. - Seohyun Choi, 2018/05/08 14:56
오른쪽으로 계산하라는 말이 오른쪽에 있는 식부터 계산하라는 의미였습니다 풀이하신 것 보니 잘 푸신 것 같아요 - myyh2357, 2018/05/09 22:18

12개의 풀이가 있습니다.

import re

def split(text, type = True):
    list = []

    type1 = re.compile('[*]|[/]|[^*/]+')
    type2 = re.compile('[+]|[-]|[0-9]+')

    if type == True:
        result = type1.finditer(text)
    else:
        result = type2.finditer(text)

    for item in result:
        list.append(item.group())

    return list

def addandsubstract(text):
    list = split(text, False)
    result = float(list[0])
    i = 1
    while i < len(list):
        if list[i] == "+":
            result += float(list[i+1])
        else:
            result -= float(list[i+1])
        i += 2

    return result

def calculate(text):
    list = split(text, True)
    print(list)
    result = addandsubstract(list[0])
    i = 1
    while i < len(list):
        if list[i] == "*":
            result *= addandsubstract(list[i+1])
        else:
            result /= addandsubstract(list[i+1])
        i += 2

    return result

test = '2+3*12/15-9'

print(calculate(test))

2018/05/08 08:00

윤민일

import re

k = '2+3*12/15-9'

def solution(a) : 
    tmp1 = re.split('(\D)', a)

    for i in range(len(tmp1)-1):
        if tmp1[i]=="+" or tmp1[i]=="-":
            tmp1[i+1] = str(eval("".join(tmp1[i-1:i+2])))
            tmp1[i-1] = ""
            tmp1[i] = ""
    return(eval("".join(tmp1)))
solution(k) # 10

2018/05/08 14:53

Seohyun Choi

+-가 없어질때까지 치환하고, */를 계산하는 방법이 있지만 다른분들이 풀이를 하셔서 저는 후위표기법으로 변환후에 계산하는것으로 풀어보았습니다.

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.StringTokenizer;

/**
 * @author Kimseongsu
 * @see http://codingdojang.com/scode/590
 * 
 */
public class P590 {

    public static void main(String[] args) {
        final String INPUT = "2+3*12/15-9";
//      System.out.println("input: " + INPUT);

        final List<String> postfix = toPostfix(INPUT);
//      System.out.println("postfix: [" + String.join(", ", postfix) + "]");

        final int result = calc(postfix);
        System.out.println(result);
    }

    /**
     * 입력값을 후위표기법으로 변환
     */
    private static List<String> toPostfix(final String input) {
        List<String> infix = new ArrayList<>();
        StringTokenizer st = new StringTokenizer(input, "-+*/", true);
        while (st.hasMoreTokens()) {
            infix.add(st.nextToken());
        }

        List<String> postfix = new ArrayList<>();
        Stack<String> operator = new Stack<>(); // 연산자 임시 저장 스택

        for (int i=infix.size()-1; i>=0; i--) { // 오른쪽부터
            String exp = infix.get(i);
            if (isNumber(exp)) {
                postfix.add(exp);
            } else {
                if (operator.isEmpty() || getOpPriority(exp) > getOpPriority(operator.lastElement())) {
                    operator.push(exp);
                } else {
                    while (!operator.isEmpty() && getOpPriority(exp) <= getOpPriority(operator.lastElement())) {
                        postfix.add(operator.pop());
                    }
                    operator.push(exp);
                }
            }
        }

        while (!operator.isEmpty()) {
            postfix.add(operator.pop());
        }

        return postfix;
    }

    private static boolean isNumber(String str) {
        return str.matches("\\d+");
    }

    private static int getOpPriority(String str) {
        if (str.equals("+") || str.equals("-")) {
            return 2;
        }
        if (str.equals("*") || str.equals("/")) {
            return 1;
        }
        throw new RuntimeException("Unsupported Operator.");
    }

    private static int calc(List<String> postfix) {
        Stack<Integer> result = new Stack<>();
        for (String exp : postfix) {
            if (isNumber(exp)) {
                // 숫자일경우 그대로 스택에 push
                result.push(Integer.valueOf(exp));
            } else {
                // 오른쪽부터 후위표기법으로 바꾸었으니, 먼저 들어간게 오른쪽값이 됨.
                final int right = result.pop();
                final int left = result.pop();
                // 연산자에 따라 계산후, 다시 스택에 push
                if (exp.equals("+")) {
                    result.push(right + left);
                } else if (exp.equals("-")) {
                    result.push(right - left);
                } else if (exp.equals("*")) {
                    result.push(right * left);
                } else if (exp.equals("/")) {
                    result.push(right / left);
                } else {
                    throw new RuntimeException("Unsupported Operator.");
                }
            }
//          final String stackLog = String.join(", ", Arrays.asList(result.toArray()).stream().map(String::valueOf).collect(Collectors.toList()));
//          System.out.println("exp: " + exp + ", \tstack: [" + stackLog + "]");
        }
        return result.pop();    // 마지막에 남은 숫자가 결과값.
    }
}

2018/05/11 17:54

Seongsu Kim

#include<iostream>
#include"stdafx.h"

void Make_My_List(const string str,list<char> &lt)
{
    for (string::size_type i = 0; i < str.size(); i++)
    {
        if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
        {
            lt.push_front(str[i]);
        }
    }
}
void extract_num(const string str, list<int> &num_lt)
{
    int branch=0;
    for (string::size_type i = 0; i < str.size(); i++)
    {
        if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
        {
            int k = 0;
            char temp[10];
            for (int j=branch; j<i; j++)
            {
                temp[k] = str[j];
                k++;
            }
            num_lt.push_front(atoi(temp));
            branch = i+1;
        }
    }
    int k = 0;
    char temp[10];
    while (branch <= str.size())
    {
        temp[k++] = str[branch++];
    }
    num_lt.push_front(atoi(temp));
}
void Calculator(const string str,list<char> &lt,list<int> &num_lt)
{
    if (lt.size() == 0)
        return ;
    else
    {
        list<char>::iterator iter1 = lt.begin();
        list<int>::iterator iter2 = num_lt.begin();
        if (*iter1 == '*' || *iter1 == '/')
        {
            list<char>::iterator comp;
            if (lt.size() == 1)
                comp = lt.begin();
            else comp = ++iter1;
            if (*comp == '+'|| *comp == '-')
            {
                int a, b;
                iter2++, a = *iter2;
                iter2 = num_lt.erase(iter2);
                b = *iter2, num_lt.erase(iter2);
                if (*comp == '+') num_lt.push_front(b + a);
                else num_lt.push_front(b - a);
                lt.erase(comp);
            }
            else
            {
                if (lt.size() > 1)
                    --iter1;
                int a, b;
                a = *iter2;
                iter2++;
                b = (*iter2);
                num_lt.pop_front();
                num_lt.pop_front();
                if (*iter1 == '*') num_lt.push_front(b*a);
                else num_lt.push_front(b / a);
                lt.pop_front();
            }
        }
        else
        {
            int a, b;
            a = *iter2;
            iter2++;
            b = (*iter2);
            num_lt.pop_front();
            num_lt.pop_front();
            if(*iter1=='+') num_lt.push_front(b+a);
            else num_lt.push_front(b - a);
            lt.pop_front();
        }
        return Calculator(str, lt, num_lt);
    }
}

int main()
{
    string str="2+3*12/15-9";
    list<char> lt;
    list<int> num_lt;
    int result=0;
    //cout << "input:";
    //cin >> str;
    Make_My_List(str, lt);
    extract_num(str, num_lt);
    Calculator(str, lt, num_lt);
    cout << num_lt.front();
}

stl공부중인데 아직 너무 미숙하네요... 도중에 deque로 바꾸려고 했으나 오기 생겨서 끝까지list로 풀었네요;

2018/05/20 23:06

Hujinsu

t = input('입력: ')
x = list(i for i in t if i == '+' or i == '-' or i == '*' or i == '/')
y = t.replace('+',' ').replace('-',' ').replace('*',' ').replace('/',' ').split()

for i in range(len(x)-1,-1,-1):
    if x[i] == '-' or x[i] == '+':
        y[i] = str(eval(y[i] + x.pop(i) + y.pop(i+1)))
for i in sorted(range(len(x)),reverse=True):
    y[i] = str(eval(y[i] + x.pop(i) + y.pop(i+1)))

print('출력: {}'.format(y[0]))

입력: 2+3*12/15-9
출력: 10.0

2018/06/27 19:05

Creator

import re

s = '2+3*12/15-9'

while len(re.findall("\+|-", s)) > 0:
    found = re.findall("\d+[\+|-]\d+", s)[0]
    s = s.replace(found, str(eval(found)), 1)

print(eval(s))

2018/06/29 16:35

Wannagenie

def parse(string):
    for op in '+-*/':
        string = string.replace(op, ' ' + op + ' ')

    return string.split()


def eval_(src):
    # 더하기 빼기
    lst = []
    while src:
        t = src.pop()
        if t not in '+-':
            lst = [t] + lst
        else:
            lst[0] = str(eval(src.pop() + t + lst[0]))

    # 곱하기 나누기
    val = lst.pop()
    while lst:
        op, t = lst.pop(), lst.pop()
        val = str(eval(t + op + val))

    return val


#inp = input()
inp = '2+3*12/15-9'
print(eval_(parse(inp)))

2018/08/29 01:28

Noname

inp=input("사칙연산을 입력하십시오: ") #2+3*12/15-9
elst=[]  # "*" 또는 "/"를 받기 위한 빈 리스트 생성
for num in inp:
    if num=="*" or num=="/":  #inp의 요소가 "*" 또는 "/"이면 elst에 추가하고 inp에 "*"이나 "/"은 " "(공백)으로 대체
        elst.append(num)
        inp=inp.replace(num," ")
inp=inp.split() #inp를 공백을 기준으로 나눔 -> ['2+3', '12', '15-9']
lst=[] #계산 결과를 받기 위한 빈 리스트 생성
for num in inp:  #inp의 요소들을 계산하여 lst에 추가
    result=eval(num)
    lst.append(result)
lst=list(map(str,lst))  #계산결과는 숫자형태이므로 문자형으로 전환
i=0
for eq in elst:  #lst의 홀수번째에 "*"나 "/"를 삽입
    lst.insert(2*i+1,eq)
    i+=1
print(eval("".join(lst))) #lst를 문자열화 시켜서 계산. #10.0

2020/02/13 14:39

박시원

import re

def solution(s) :
    numCom, opCom = re.compile("\d*\.?\d+"), re.compile("[*+-\/]{1}")
    nums, ops = numCom.findall(s), opCom.findall(s)

    while True :
        for opIndex in range(len(ops)-1, -1, -1) :
            if ops[opIndex] in ('+', '-') :
                nums[opIndex] = str(eval(nums[opIndex]+ops[opIndex]+nums[opIndex+1]))
                p1, p2 = nums.pop(opIndex+1), ops.pop(opIndex)
        if not '+' in ops and not '-' in ops :
            break

    while True :
        for opIndex in range(len(ops)-1, -1, -1) :
            if ops[opIndex] in ('*', '/') :
                nums[opIndex] = str(eval(nums[opIndex]+ops[opIndex]+nums[opIndex+1]))
                p1, p2 = nums.pop(opIndex+1), ops.pop(opIndex)
        if not '*' in ops and not '/' in ops :
            break

    return float(nums[0])

solution('2+3*12/15-9')

원시적인(?) 방법이라고 생각하면서 풀었는데, 풀고나서 보니 이렇게 푸신 분들도 좀 계시네요. 연산자랑 숫자를 전부 분리한 다음, 첫 번째 루프에서 덧셈과 뺄셈을, 두 번째 루프에서 곱셈과 나눗셈을 오른쪽부터 순서대로 계산하도록 했습니다.

결과

10.0

2020/03/09 16:27

GG

python 3.8

import re
a='2+3*12/15-9'   # 부호가 있는 숫자는 고려하지 않았음
b=re.findall(r'[+*/\-]',a)  # 부호부 분리
c=re.findall(r'\d+',a) # =re.split(r'\D',a) 숫자부
         # b=re.split(r'(\D)',a) 숫자와 부호 분리
i=len(b)-1          
while i>= 1:  # +,- 고려 역순 계산
    if b[i] in ['*','/']  and b[i-1] in ['-','+']:  
        c[i]=str(eval(c[i-1]+b[i-1]+c[i]))
        c[i-1]=str(eval(c[i]+b[i]+c[i+1]))
        i=i-2
    else:
        c[i]=str(eval(c[i]+b[i]+c[i+1]))
        i=i-1
print(c[0])    # sum

2020/03/10 13:00

mr. gimp

+,-항만 미리 계산되면 선순위던 후순위 계산이던 의미가 없어 더 짧은 코딩이 가능할 수 있군요. - mr. gimp, 2020/03/11 03:30

자바로 풀어봤습니다.

import java.util.ArrayList;
import java.util.Scanner;
import java.util.List;

public class calculator {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        ArrayList<String> elements = new ArrayList<>();
        ArrayList<String> result = new ArrayList<>();

        // 입력
        System.out.print("괄호가 없는 사칙연산식 입력:");
        String equation = scan.nextLine();
        String[] signs = {"+", "-", "*", "/"};

        // 숫자, 기호 분리해서 리스트에 저장하기
        equation = equation.replaceAll(" ", "");
        while(equation.length()>0) {
            // equation내에 연산 기호가 없으면 숫자만 있다고 판단하여 리스트에 저장
            if(equation.contains("+")==false&equation.contains("-")==false&
               equation.contains("*")==false&equation.contains("/")==false) {
                    elements.add(equation);
                    equation = "";
            }

            loop1 :
            for(int i=0; i<equation.length(); i++) {
                String element = equation.substring(i, i+1);

                loop2 :
                for(String sign : signs) {
                    if(element.equals(sign)) {
                        // 연산 기호 앞에 있는 숫자를 리스트에 저장
                        elements.add(equation.substring(0, i));
                        // 연산 기호를 리스트에 저장
                        elements.add(equation.substring(i, i+1));
                        // 리스트에 저장하지 않는 부분을 잘라서 다시 equation에 저장
                        equation = equation.substring(i+1, equation.length());
                        break loop1;
                    }
                }
            }
        }

        // +과 -부터 계산
        String[] firstSigns = {"+", "-"};
        loop3 :
        for(int i=elements.size()-1; i>=0; i--) {
            loop4 :
            for(String sign : firstSigns) {
                if(elements.get(i).equals(sign)) {
                    // i-2번째까지 elements 객체들을 result 리스트에 임시 저장
                    for(int j=0; j<i-1; j++) {
                        result.add(elements.get(j));
                    }               

                    // 숫자들을 eleements 리스트에서 뽑아서 double형으로 변환
                    double m = Double.parseDouble(elements.get(i-1));
                    double n = Double.parseDouble(elements.get(i+1));

                    // 계산하고 result 리스트에 저장
                    if(sign.equals("+")) {
                        result.add(String.valueOf(m+n));
                    }else {
                        result.add(String.valueOf(m-n));
                    }

                    // 나머지 부분 result 리스트에 저장
                    for(int j=i+2; j<elements.size(); j++) {
                        result.add(elements.get(j));
                    }

                    // result 리스트를 elements 리스트에 복사 붙어넣기
                    elements.clear();
                    for(int j=0; j<result.size(); j++) {
                        elements.add(result.get(j));
                    }                       
                    result.clear();
                    break loop4;
                }
            }
        }

        // *과 / 계산
        String[] secondSigns = {"*", "/"};
        loop5 :
        for(int i=elements.size()-1; i>=0; i--) {
            loop6 :
            for(String sign : secondSigns) {
                if(elements.get(i).equals(sign)) {
                    // i-2번째까지 elements 객체들을 result 리스트에 임시 저장
                    for(int j=0; j<i-1; j++) {
                        result.add(elements.get(j));
                    }               

                    // 숫자들을 eleements 리스트에서 뽑아서 double형으로 변환
                    double m = Double.parseDouble(elements.get(i-1));
                    double n = Double.parseDouble(elements.get(i+1));

                    // 계산하고 result 리스트에 저장
                    if(sign.equals("*")) {
                        result.add(String.valueOf(m*n));
                    }else {
                        result.add(String.valueOf(m/n));
                    }

                    // 나머지 부분 result 리스트에 저장
                    for(int j=i+2; j<elements.size(); j++) {
                        result.add(elements.get(j));
                    }

                    // result 리스트를 elements 리스트에 복사 붙어넣기
                    elements.clear();
                    for(int j=0; j<result.size(); j++) {
                        elements.add(result.get(j));
                    }                       
                    result.clear();
                    break loop6;
                }
            }
        }

        // 결과 출력
        for(int i=0; i<elements.size(); i++) {
            System.out.println("결과: "+elements.get(i));
        }
    }
}

2022/06/16 16:10

유로

def calc(op, v1, v2):
    if op == '+': v1 += v2
    elif op == '-': v1 -= v2
    elif op == '*': v1 *= v2
    elif op == '/': v1 //= v2
    return v1

problem = '2+3*12/15-9'
nums = []
ops = []
su, op = '', ''
for p in problem:
    if p == '*' or p == '/':
        if op != '':
            nums[-1] = calc(op, nums[-1], int(su))
        else:
            nums.append(int(su))
        ops.append(p)
        su, op = '', ''
    elif p == '+' or p == '-':
        nums.append(int(su))
        op, su = p, ''
    else:
        su += p
if op == '+' or op == '-':
    nums[-1] = calc(op, nums[-1], int(su))
else:
    nums.append(int(su))

for i in range(len(ops)):
    nums[0] = calc(ops[i],nums[0], nums[i+1])

print('\n\t{0} = {1}'.format(problem,nums[0]))

2023/09/25 21:20

insperChoi

목록으로