현우는 초등학생인 여동생의 수학 숙제를 도와주고 있었다.
현우는 동생을 좀 더 잘 가르치고 싶어 답을 구하는 과정을 되도록 자세히 알려주려고 오른쪽에서 왼쪽으로 순차적으로 계산하는 과정을 보여주고자 한다.
단, 일반적인 수식과 같이 곱하기(*)와 나누기(/)는 연산자 우선순위가 높으므로 먼저 계산해야 한다. 현우를 도와 수식을 입력 받으면 계산과정과 결과를 보여주는 코드를 작성하도록 하자.
한 줄로 숫자와 사칙 연산 기호 +, -, *, /로 이루어진 수식이 입력된다.
한 줄마다 오른쪽에서 왼쪽으로 한 단계씩 계산된 결과와 나머지 수식을 출력한다.
9+5-4+8
14-4+8
10+8
18
5+6*3-6/2+5
5+18-6/2+5
5+18-3+5
23-3+5
20+5
25
17개의 풀이가 있습니다.
def solve(n):
l=n
count=0
for i in range(len(l)):
if n[i] in '+-':
count+=1
if count>=1:
l=str(eval(n[:i]))+n[i:]
print(l)
count=0
return eval(l)
print(solve('12+15*6+56/4+1+51'))
>>>12+15*6+56/4+1+51
102+56/4+1+51
116.0+1+51
117.0+51
168.0
좀있다난이도업 풀어야징
split해서 각각을 리스트로 만들어서 */ 연산 먼저 처리하고 +-처리하도록 구현했습니다. 먼저 처리하면 순번이 엇갈리는 문제가 발생해서 재귀함수로 구현했습니다.
input1 = '12+15*6+56/4+1+51'
def calc_once(input1):
print(input1)
if input1.isdigit():
return input1
for i in '+-*/':
input1 = input1.replace(i, ' '+ i + ' ')
arr1 = input1.split()
for i in range(len(arr1)):
if arr1[i] in '*/':
data = ("".join(arr1[:i-1]) + str(eval(arr1[i-1] + arr1[i] + arr1[i+1])) + "".join(arr1[i+2:]))
return calc_once(data)
for i in range(len(arr1)):
if arr1[i] in '+-':
data = ("".join(arr1[:i-1]) + str(eval(arr1[i-1] + arr1[i] + arr1[i+1])) + "".join(arr1[i+2:]))
return calc_once(data)
calc_once(input1)
#output
12+15*6+56/4+1+51
12+90+56/4+1+51
12+90+14.0+1+51
102+14.0+1+51
116.0+1+51
117.0+51
168.0
def i(e,f):
return e.index(f) if f in e else len(e)+1
def cal1(e):
print(e)
e = list(e)
for x in range(e.count('-')+e.count('+')+e.count('*')+e.count('/')):
if e.count('-')+e.count('+')+e.count('*')+e.count('/') == 1:
print(eval(''.join(e)))
exit()
ix = min(i(e,'*'),i(e,'/')) if '*' in e or '/' in e else min(i(e,'+'),i(e,'-'))
c1,c2 = ix-1,ix+1
while True:
if e[c2] in '+-*/' and e[c1] in '+-*/':
break
else:
c1 -= 0 if e[c1] in '+-*/' else 1
c2 += 0 if e[c2] in '+-*/' else 1
if c1 < -1:
c1 = -1
e[c2-1] = str(eval(''.join(e[c1+1:c2])))
del e[c1+1:c2-1]
print(''.join(e))
#공백이 있을 때
def cal2(e):
print(e)
e = e.split()
for x in range(e.count('-')+e.count('+')+e.count('*')+e.count('/')):
ix = min(i(e,'*'),i(e,'/')) if '*' in e or '/' in e else min(i(e,'+'),i(e,'-'))
e[ix+1] = str(eval(''.join(e[ix-1:ix+2])))
del e[ix-1:ix+1]
print(''.join(e))
import re
def slow_cal(line):
nums, ops = re.findall('\d+', line), re.findall('[+\-*/]', line)
for o in ops :
if o in "*/":
idx = ops.index(o)
a, b = nums.pop(idx), nums.pop(idx)
nums.insert(idx, str(int(eval(a+o+b))))
ops.remove(o)
pp(nums, ops)
while len(ops) > 0 :
nums.insert(0, str(int(eval(nums.pop(0)+ops.pop(0)+nums.pop(0)))))
pp(nums, ops)
def pp(nums, ops):
i, r = 0, ""
while i < len(ops):
r += nums[i] + ops[i]
i += 1
print(r + nums[i])
slow_cal("5+6*3-6/2+5")
eval() 일부러 안 쓰고 했습니다.
dict() is not callable....
몰랐던 걸 알았네요.
def tokenize(str):
for op in '*/+-':
str = str.replace(op, ' ' + op + ' ')
return str.split()
def calc(exp, i):
opr1, op, opr2 = int(exp[i - 1]), exp[i], int(exp[i + 1])
func = [lambda x, y: x * y, lambda x, y: x // y, lambda x, y: x + y, lambda x, y: x - y]
newterm = str(func['*/+-'.index(op)](opr1, opr2))
return exp[:i-1] + [newterm] + exp[i + 2:]
def reduce_once(exp):
for i in range(len(exp)):
if exp[i] in '*/':
return calc(exp, i)
for i in range(len(exp)):
if exp[i] in '+-':
return calc(exp, i)
def reduce(exp_str):
print(exp_str)
exp = tokenize(exp_str)
while len(exp) > 1:
exp = reduce_once(exp)
print(''.join(exp))
reduce('9+5-4+8')
reduce('5+6*3-6/2+5')
import re
t= re.compile('[\d]*([+]|[-])[\d]*')
t2= re.compile('[\d]*([*]|[/])[\d]*')
a ='9+5-4+8'
b ='5+6*3-6/2+5'
def func(a):
while t.search(a):
if t.search(a):
a=a.replace(t.search(a).group(0),str(eval(t.search(a).group(0))))
print(a)
while t2.search(b):
if t2.search(b):
b=b.replace(t2.search(b).group(0),str(int(eval(t2.search(b).group(0)))))
print(b)
func(b)
print('-------------------')
func(a)
처음에 만든 방식입니다.
sprit으로 나누고 연산기호 하나 계산 후 다시 String으로 합치는 것을 반복합니다.
위 과정을 while로 돌렸습니다.
문제에서 제시한 예시는 정상적으로 출력됩니다만.. 첫 숫자가 음수이거나 답이 음수가 되는 경우 정상적인 출력이 되지 않았습니다.
public static void main(String[] args) {
String math = "3434+523*6*3-4312/2+245*45";
String[] num = math.split("[^0-9]");
String[] sign = math.split("[0-9]+");
while (!math.matches("[0-9]+")) {
for (int i = 1; i < sign.length; i++) {
if (sign[i].matches("[*/]") || (!math.matches(".*[*/].*") && sign[i].matches("[\\+\\-]"))) {
int a = Integer.valueOf(num[i - 1]);
int b = Integer.valueOf(num[i]);
num[i - 1] = (sign[i].equals("*") ? a * b
: sign[i].equals("/") ? a / b : sign[i].equals("+") ? a + b : a - b) + "";
num[i] = sign[i] = "";
math = math(num, sign, "");
num = math.split("[^0-9]");
sign = math.split("[0-9]+");
System.out.println(math);
break;
}
}
}
}
private static String math(String[] num, String[] sign, String math) {
for (int i = 0; i < num.length; i++)
math += i == num.length - 1 ? num[i] : num[i] + sign[i + 1];
return math;
}
두번째로 만든 코드입니다.
하나의 배열에 전부 나눠넣어 곱하기와 나누기 연산을 끝낸 후
새로운 for로 더하기 빼기를 했습니다.
음수냐 아니냐에 따라 sprit으로 나눠지는 위치가 달라 고생을 하였습니다.
public static void main(String[] args) {
String input = "5*1217+4*7+3*123+8*3*4*5*6*7*2/2+3";
String[] math = (input.replaceAll("\\+", " +").replaceAll("-", " -").replaceAll("\\*", " *").replaceAll("/",
" /")).split(" ");
for (int i = math[0].equals("") ? 2 : 1; i < math.length; i++) {
if (math[i].matches("[*/].*")) {
int temp = Check(math, i - 1);
int a = Integer.valueOf(math[temp]);
int b = Integer.valueOf(math[i].substring(1));
math[temp] = (math[i].startsWith("*") ? a * b : a / b) + "";
math[i] = "";
print(math);
}
}
for (int i = 2; i < math.length; i++)
if (!math[i].equals("")) {
int temp = math[0].equals("") ? 1 : 0;
math[temp] = (Integer.valueOf(math[temp]) + Integer.valueOf(math[i])) + "";
math[i] = "";
print(math);
}
}
private static void print(String[] math) {
for (int i = 0; i < math.length; i++)
System.out.print(math[i].matches("[0-9]+")
? math[0].equals("") ? i == 1 ? math[i] : "+" + math[i] : i == 0 ? math[i] : "+" + math[i]
: math[i]);
System.out.println();
}
private static int Check(String math[], int i) {
return math[i].equals("") ? Check(math, i - 1) : i;
}
쉬울줄 알고 시작했는데 막상 해보니 음수 관련 부분이 생각보다 까다로웠습니다.
사칙연산을 잘 못하여 배우는 초등학생이 음수 연산을 배웠을리는 없겠으나..........
첫자리/결과값 음수, 소수점 모두 계산 가능합니다.
import re
def cal(s):
s = print_step("\*|/", s)
s = print_step("\+|-", s)
def print_step(p, s):
while re.findall(p, s[1:] if s[0] == "-" else s):
pattern = "[-+]?\d+[.]?\d*[" + p + "][-+]?\d+[.]?\d*"
found = re.findall(pattern, s)[0]
val = str(eval(found))
val = val if val[0] == "-" else "+" + val
s = s.replace(found, val)
s = s[1:] if s[0] == "+" else s
print(s)
return s
s = "5+6*3-6/2+5"
cal(s)
Ruby
def calc(exp)
exp = exp.split(/(\d+)/).reject(&:empty?) if exp.is_a? String
idx = (exp.index {|e| e =~ /[*\/]/} || exp.index {|e| e =~ /[+-]/})&.pred
calc(exp.insert(idx, eval(exp.slice!(idx, 3)*'')).tap {|e| puts e*''}) if idx
end
Test
expect{ calc("5+6*3-6/2+5") }.to output("5+18-6/2+5\n" +
"5+18-3+5\n" +
"23-3+5\n" +
"20+5\n" +
"25\n").to_stdout
def teach_calc(s):
for i in '*/+-': s = s.replace(i, f'{i:^3}')
eq = s.split()
print(s)
idx = 0
while idx < len(eq):
if eq[idx] in '*/':
eq[idx-1: idx+2] = [str(eval(''.join(eq[idx-1:idx+2])))]
print(''.join(eq))
else: idx += 1
while len(eq) > 1:
eq[:3] = [str(eval(''.join(eq[:3])))]
print(''.join(eq))
test = '5+6*3-6/2+5'
teach_calc(test)
5 + 6 * 3 - 6 / 2 + 5
5+18-6/2+5
5+18-3.0+5
23-3.0+5
20.0+5
25.0
#include<iostream>
#include<string>
using namespace std;
int main()
{
string n;
// 입력
cin >> n;
// 첫번째 인덱스 저장
int sum = stoi(n.substr(0, n.find('+' | '-', 0)));
int index;
for (int i = 0; i <n.length(); i++)
{
if (n[i] == '+')
{
sum += stoi(n.substr(i + 1, n.find('+' | '-', i)));
cout << sum;
if (n.find('+', i + 1) < n.find('-', i + 1))
index = n.find('+', i);
else
index = n.find('-', i);
for (int j = index; j < n.length(); j++)
cout << n[j];
cout << endl;
}
else if (n[i] == '-')
{
sum -= stoi(n.substr(i + 1, n.find('+' | '-', i)));
cout << sum;
if (n.find('+', i + 1) < n.find('-', i + 1))
index = n.find('+', i);
else
index = n.find('-', i);
for (int j = index; j < n.length(); j++)
cout << n[j];
cout << endl;
}
}
}
예시 1 버전도 해볼께요 ㅎㅎ...
// ===============================================
String st = "5+6*3-6/2+5";
String math = "+-*/";
String temp1;
String temp2;
String temp3;
String temp4;
String temp5;
String temp6;
for (int i = 0; i < st.length(); i++) {
if (st.charAt(i) == math.charAt(2)) {
temp1 = st.substring(2, 3);
temp2 = st.substring(4, 5);
System.out.print(st.substring(0, 2));
System.out.print((Integer.valueOf(temp1) * Integer.valueOf(temp2)));
System.out.println(st.substring(5, 11));
}
if (st.charAt(i) == math.charAt(3)) {
temp1 = st.substring(2, 3);
temp2 = st.substring(4, 5);
temp3 = st.substring(6, 7);
temp4 = st.substring(8, 9);
System.out.print(st.substring(0, 2));
System.out.print((Integer.valueOf(temp1) * Integer.valueOf(temp2)));
System.out.print(st.substring(5, 6));
System.out.print((Integer.valueOf(temp3) / Integer.valueOf(temp4)));
System.out.println(st.substring(9, 11));
}
}
if (st.charAt(0) == st.charAt(0)) {
temp1 = st.substring(2, 3);
temp2 = st.substring(4, 5);
temp3 = st.substring(6, 7);
temp4 = st.substring(8, 9);
temp5 = st.substring(0, 1);
System.out.print(Integer.valueOf(temp5) + (Integer.valueOf(temp1) * Integer.valueOf(temp2)));
System.out.print(st.substring(5, 6));
System.out.print((Integer.valueOf(temp3) / Integer.valueOf(temp4)));
System.out.println(st.substring(9, 11));
}
if (st.charAt(1) == st.charAt(1)) {
temp1 = st.substring(2, 3);
temp2 = st.substring(4, 5);
temp3 = st.substring(6, 7);
temp4 = st.substring(8, 9);
temp5 = st.substring(0, 1);
System.out.print(Integer.valueOf(temp5) + (Integer.valueOf(temp1) * Integer.valueOf(temp2))
- (Integer.valueOf(temp3) / Integer.valueOf(temp4)));
System.out.println(st.substring(9, 11));
}
if (st.charAt(0) == st.charAt(0)) {
temp1 = st.substring(2, 3);
temp2 = st.substring(4, 5);
temp3 = st.substring(6, 7);
temp4 = st.substring(8, 9);
temp5 = st.substring(0, 1);
temp6 = st.substring(10, 11);
System.out.print(Integer.valueOf(temp5) + (Integer.valueOf(temp1) * Integer.valueOf(temp2))
- (Integer.valueOf(temp3) / Integer.valueOf(temp4)) + Integer.valueOf(temp6));
}
import re
def calc(s):
p1 = re.compile('\d+[*/]\d+')
p2 = re.compile('\d+[+-]\d+')
while p1.search(s):
print(s)
m1 = p1.search(s)
t = str(int(eval(m1.group())))
s = p1.sub(t, s, count=1)
while p2.search(s):
print(s)
m2 = p2.search(s)
t = str(int(eval(m2.group())))
s = p2.sub(t, s, count=1)
print(s)
>>> calc('9+5-4+8')
9+5-4+8
14-4+8
10+8
18
>>> calc('5+6*3-6/2+5')
5+6*3-6/2+5
5+18-6/2+5
5+18-3+5
23-3+5
20+5
25
import re
INP = input("INPUT : ")
c = re.compile("\d*\.?\d+[*/]\d*\.?\d+")
while True : #먼저 *, / 를 계산합니다.
SEP = c.search(INP)
if SEP == None : #search의 결과가 None일 경우 루프를 나갑니다.
break
else :
print(c.sub(str(eval(c.search(INP).group(0))), INP, count = 1)) #search의 결과 중 제일 첫 번째 결과를 계산해 결과를 바꿔넣습니다.
INP = c.sub(str(eval(c.search(INP).group(0))), INP, count = 1) #문자열을 갱신합니다.
d = re.compile("\d*\.?\d+[+-]\d*\.?\d+")
while True : # +, -를 계산합니다.
PPE = d.search(INP)
if PPE == None :
break
else :
print(d.sub(str(eval(d.search(INP).group(0))), INP, count = 1))
INP = d.sub(str(eval(d.search(INP).group(0))), INP, count = 1)
결과
INPUT : 12+15*6+56/4+1+51
12+90+56/4+1+51
12+90+14.0+1+51
102+14.0+1+51
116.0+1+51
117.0+51
168.0
inp=input("사칙연산을 입력하십시오: ")
elst=[]
for num in inp:
if num=="+" or num=="-": #곱셈과 나눗셈을 먼저 해야하니 +와 -를 분리하여 elst에 넣음
elst.append(num)
inp=inp.replace(num," ")
inp=inp.split()
i=0
for eq in elst: #+와 -를 홀수번째에 삽입
inp.insert(2*i+1,elst[i])
i+=1
for i in range(len(inp)): #곱셈(*)과 나눗셈(/) 계산
if "*" in inp[i] or "/" in inp[i]:
inp[i]=str(eval(inp[i]))
print("".join(inp))
while len(inp)!=1: #리스트의 첫번째, 두번째, 세번째 요소를 뽑아 계산 후 리스트의 첫번째 요소로 넣는 것을 반복
a=inp.pop(0)
b=inp.pop(0)
c=inp.pop(0)
num=[str(eval(a+b+c))]
inp=num+inp
print("".join(inp))
결과
사칙연산을 입력하십시오: 5+6*3-6/2+5
5+18-6/2+5
5+18-3.0+5
23-3.0+5
20.0+5
25.0
사칙연산을 입력하십시오: 12+15*6+56/4+1+51
12+90+56/4+1+51
12+90+14.0+1+51
102+14.0+1+51
116.0+1+51
117.0+51
168.0
다만 위 코드는, 2+3 * 12/15-9와 같은 경우에 2+36/15-9, 2+2.4-9, 4.4-9, -4.6 이런식이 아니라, 바로 2+2.4-9로 곱셈과 나눗셈이 연속될 경우 한꺼번에 계산하는 단점이 있네요. 나중에 보고 다른 방법으로 도전해보겠습니다.
output = [i for i in input().split(" ")]
while True:
for i in output:
if i == "*" or i == "/":
idx = output.index(i)
num1 = int(output.pop(idx -1))
calculator = output.pop(idx -1)
num2 = int(output.pop(idx -1))
if i == "*":
output.insert(idx-1, int(num1 * num2))
if i == "/":
output.insert(idx-1, int(num1 / num2))
print(*output)
break
if "*" not in output and "/" not in output:
break
while True:
for i in output:
if i == "+" or i == "-":
idx = output.index(i)
num1 = int(output.pop(idx -1))
calculator = output.pop(idx -1)
num2 = int(output.pop(idx -1))
if i == "+":
output.insert(idx-1, int(num1 + num2))
if i == "-":
output.insert(idx-1, int(num1 - num2))
print(*output)
break
if "+" not in output and "-" not in output:
break
using System;
using System.Collections.Generic;
namespace solution
{
class Program
{
static void Main(string[] args)
{
//string prob = "12+15*6+56/4+1+51";
Console.WriteLine("계산할 문제를 입력하세요:");
string prob = Console.ReadLine();
calcInOrder(prob);
}
private static void calcInOrder(string prob)
{
List<string> plist = new List<string>();
string s = "";
for (int i = 0; i < prob.Length; i++)
{
if (prob[i] == ' ')
continue;
else if (!char.IsDigit(prob[i]))
{
plist.Add(s);
s = "";
plist.Add(prob[i].ToString());
}
else
s += prob[i];
}
plist.Add(s);
Console.WriteLine(string.Join(" ", plist));
while(plist.Count > 2)
{
if (plist.Contains("*") || plist.Contains("/"))
{
for (int i = 0; i < plist.Count; i++)
{
if (plist[i] == "*")
{
int su = int.Parse(plist[i - 1]) * int.Parse(plist[i + 1]);
for (int n = 0; n < 3; n++)
plist.RemoveAt(i - 1);
plist.Insert(i - 1, su.ToString());
break;
}
else if (plist[i] == "/")
{
int su = int.Parse(plist[i - 1]) / int.Parse(plist[i + 1]);
for (int n = 0; n < 3; n++)
plist.RemoveAt(i - 1);
plist.Insert(i - 1, su.ToString());
break;
}
}
}
else if (plist.Contains("+") || plist.Contains("-"))
{
for (int i = 0; i < plist.Count; i++)
{
if (plist[i] == "+")
{
int su = int.Parse(plist[i - 1]) + int.Parse(plist[i + 1]);
for (int n = 0; n < 3; n++)
plist.RemoveAt(i - 1);
plist.Insert(i - 1, su.ToString());
break;
}
else if(plist[i] == "-")
{
int su = int.Parse(plist[i - 1]) - int.Parse(plist[i + 1]);
for (int n = 0; n < 3; n++)
plist.RemoveAt(i - 1);
plist.Insert(i - 1, su.ToString());
break;
}
}
}
Console.WriteLine("= {0}",string.Join(" ", plist));
}
}
}
}