어제 날라간 posfix 계산기를 다시 코딩해봤다.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
def postfix_calculator(expression):
operator = ['+', '-', '*', '/', '^', '%'] #'^', '%'는 '*', '/'와 동일한 우선순위를 갖는다.
operand = ['0', '1', '2', '3', '4' ,'5', '6' ,'7','8', '9'] #식을 문자열로 입력받으므로 문자열로 처리함.
opstack = []
outstack = []
calcstack = []
for factor in expression: #postfix로 변환하는 과정
if factor in operand:
outstack.append(factor)
elif factor == '(':
opstack.append(factor)
elif factor == ')':
while True:
x = opstack.pop()
if x == '(':
break
outstack.append(x)
elif factor in operator: #operator임을 명시하기 위해 적었음.
if (factor == ('+' or '-')) and (operator in ['*', '/', '^', '%']):
outstack.append(opstack.pop())
else:
opstack.append(factor)
#+와 -만 opstack에서 다른 높은 연산자를 마주쳤을 때 비켜주고, 그 경우가 아니면 들어가면 된다.
for i in range(len(opstack)):
outstack.append(opstack.pop()) #opstack의 남은 수식들을 위부터 outstack에 append한다.
#########################여기부터 계산과정###################################
for factor in outstack:
if factor in operand:
calcstack.append(factor)
elif factor in operator:
if factor == '+':
a = int(calcstack.pop())
b = int(calcstack.pop())
calcstack.append(b+a)
elif factor == '-':
a = int(calcstack.pop())
b = int(calcstack.pop())
calcstack.append(b-a)
elif factor == '*':
a = int(calcstack.pop())
b = int(calcstack.pop())
calcstack.append(b*a)
elif factor == '/':
a = int(calcstack.pop())
b = int(calcstack.pop())
calcstack.append(b/a)
elif factor == '^':
a = int(calcstack.pop())
b = int(calcstack.pop())
calcstack.append(b**a)
elif factor == '%':
a = int(calcstack.pop())
b = int(calcstack.pop())
calcstack.append(b%a)
answer = calcstack[0]
return outstack, answer
expr = input()
outstack, answer = postfix_calculator(expr)
postfix = ' '.join(s for s in outstack)
print(f'입력한 식은 "{expr}"입니다.')
print(f'postfix로 변환한 식은 "{postfix}"이고,\n계산된 값은 {answer}입니다.')
|
cs |
잘 돌아가겠구나 싶었는데 문제가 하나 발생했다.
얘가 두 자리수 이상을 인식하지 못 한다.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
def postfix_calculator(expression):
operator = ['+', '-', '*', '/', '^', '%'] #'^', '%'는 '*', '/'와 동일한 우선순위를 갖는다.
operand = [str(x) for x in range(0, 1001)] #식을 문자열로 입력받으므로 문자열로 처리함.
opstack = []
outstack = []
calcstack = []
for factor in expression: #postfix로 변환하는 과정
if factor == '(':
opstack.append(factor)
elif factor == ')':
while True:
x = opstack.pop()
if x == '(':
break
outstack.append(x)
elif factor not in operator:
outstack.append(factor)
elif factor in operator: #그냥 1대1로 연산자를 대응해도 되지만, operator임을 명시하기 위해 적었음.
if (factor == ('+' or '-')) and (operator in ['*', '/', '^', '%']):
outstack.append(opstack.pop())
else:
opstack.append(factor)
#+와 -만 opstack에서 다른 높은 연산자를 마주쳤을 때 비켜주고, 그 경우가 아니면 들어가면 된다.
for i in range(len(opstack)):
outstack.append(opstack.pop()) #opstack의 남은 수식들을 위부터 outstack에 append한다.
#########################여기부터 계산과정###################################
for factor in outstack:
if factor in operand:
calcstack.append(factor)
elif factor in operator:
if factor == '+':
a = int(calcstack.pop())
b = int(calcstack.pop())
calcstack.append(b+a)
elif factor == '-':
a = int(calcstack.pop())
b = int(calcstack.pop())
calcstack.append(b-a)
elif factor == '*':
a = int(calcstack.pop())
b = int(calcstack.pop())
calcstack.append(b*a)
elif factor == '/':
a = int(calcstack.pop())
b = int(calcstack.pop())
calcstack.append(b/a)
elif factor == '^':
a = int(calcstack.pop())
b = int(calcstack.pop())
calcstack.append(b**a)
elif factor == '%':
a = int(calcstack.pop())
b = int(calcstack.pop())
calcstack.append(b%a)
answer = int(calcstack[0])
return outstack, answer
expr = list(input().split(' '))
processed_expr = ' '.join(s for s in expr)
try:
outstack, answer = postfix_calculator(expr)
postfix = ' '.join(s for s in outstack)
print(f'입력한 식은 "{processed_expr}"입니다.')
print(f'postfix로 변환한 식은 "{postfix}"이고,\n계산된 값은 {answer}입니다.')
except:
print('오류가 발생했습니다! 계산기를 종료합니다.')
|
cs |
// 연산자는 /과 충돌이 일어나서 일단은 제외했다.
리스트 컴프리헨션을 이용해서 1부터 10000까지 연산이 가능하게 설정했고,
식을 띄어쓰기로 입력하게끔 했다
(기존에 (15*2)+1 == 1 5 * 2 + 1 과 같이 알아봤지만 ( 15 * 2 ) + 1 로 쓰면 15 * 2 + 1로 알아보게끔 함)
이외에 예외처리 문구도 넣어봤다.
*이 맨 마지막에 가있는게 에러다.
' - '는 (, )도 아니고 operator이기 때문에 else문으로 들어간다.
위에서는 이미 '^'가 자리하고 있기 때문에 elif문으로 들어간다.
factor == '-' 이기 때문에 전건을 만족한다 + opstack[-1] == '^'이기 때문에 후건도 만족, 따라서 연언문을 만족한다.
그러므로 outstack.append(opstack.pop())과 opstack.append(factor)이 실행이 되어야 하는데..
(factor == '-' or '+') and (opstack[-1] in ['*', '/', '^', '%']) // factor == ('+' or '-') and opstack[-1] in ['*', '/', '^', '%']
둘의 차이는 뭘까?
() and () 꼴로 묶였냐 안 묶였냐인 것 같다.
논리학에서도 교수님이 그렇게 괄호를 중요시하셨는데.. 그새 잊었나보다.
좌항의 경우에는 원하는 논리식이 명확한데, 오른쪽은 그렇지 않다.
조건식을 쓸 때에는 더 주의해서 괄호를 사용해야겠다.
장장 세시간에 걸쳐 완성된 계산기
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
def postfix_calculator(expression):
operator = ['+', '-', '*', '/', '^', '%'] #'^', '%'는 '*', '/'와 동일한 우선순위를 갖는다.
opstack = []
outstack = []
calcstack = []
for factor in expression: #postfix로 변환하는 과정
if factor == '(':
opstack.append(factor)
elif factor == ')':
while True:
x = opstack.pop()
if x == '(':
break
outstack.append(x)
elif factor not in operator:
outstack.append(factor)
else:
if len(opstack) == 0:
opstack.append(factor)
elif (factor == '-' or '+') and (opstack[-1] in ['*', '/', '^', '%']):
outstack.append(opstack.pop())
opstack.append(factor)
else:
opstack.append(factor)
for i in range(len(opstack)):
outstack.append(opstack.pop()) #opstack의 남은 수식들을 위부터 outstack에 append한다.
#########################여기부터 계산과정###################################
for factor in outstack:
if factor not in operator:
calcstack.append(factor)
if factor == '+':
a = calcstack.pop()
b = calcstack.pop()
calcstack.append(int(b)+int(a))
elif factor == '-':
a = calcstack.pop()
b = calcstack.pop()
calcstack.append(int(b)-int(a))
elif factor == '*':
a = calcstack.pop()
b = calcstack.pop()
calcstack.append(int(b)*int(a))
elif factor == '/':
a = calcstack.pop()
b = calcstack.pop()
calcstack.append(int(b)/int(a))
elif factor == '^':
a = calcstack.pop()
b = calcstack.pop()
calcstack.append(int(b)**int(a))
elif factor == '%':
a = calcstack.pop()
b = calcstack.pop()
calcstack.append(int(b)%int(a))
answer = int(calcstack[0])
return outstack, answer
expr = list(input().split(' '))
processed_expr = ' '.join(s for s in expr)
print(f'입력한 식은 "{processed_expr}"입니다.')
outstack, answer = postfix_calculator(expr)
postfix = ' '.join(s for s in outstack)
print(f'postfix로 변환한 식은 "{postfix}"이고,\n계산된 값은 {answer}입니다.')
|
cs |
어떻게든 물고 늘어지고 찾으면 고칠 수 있다!
'CS > 자료구조-알고리즘' 카테고리의 다른 글
(파이썬)이분 탐색 - 숫자 카드 2 (3) | 2022.08.05 |
---|---|
(다시)DFS & BFS 찍먹 (2) | 2022.06.23 |
구현 - 좌표이동 / 조건부 시각 세기 / 왕실의 나이트 (0) | 2022.06.22 |
그리디 알고리즘 (0) | 2022.06.21 |
(자료구조)순차적 자료구조/스택과 큐 - postfix 계산기와 첫 증발 (0) | 2022.06.20 |