분수
A/B
는 분자가A
, 분모가B
인 분수를 의미한다. A와 B는 모두 자연수라고 하자.
두 분수의 합 또한 분수로 표현할 수 있다. 두 분수가 주어졌을 때, 그 합을 기약분수의 형태로 구하는 프로그램을 작성하시오. 기약분수란 더 이상 약분되지 않는 분수를 의미한다.
첫째 줄과 둘째 줄에, 각 분수의 분자와 분모를 뜻하는 두 개의 자연수가 순서대로 주어진다. 입력되는 네 자연수는 모두 30,000 이하이다.
첫째 줄에 구하고자 하는 기약분수의 분자와 분모를 뜻하는 두 개의 자연수를 빈 칸을 사이에 두고 순서대로 출력한다.
✅ 분수의 합을 수행하기 위해서는 분모를 같은 수로 통분해야 하는데, 주로 두 분모의 최소공배수를 사용한다. 유클리드 호제법을 사용한 최대공약수, 최소공배수를 구하는 메서드
gcd(int, int)
,lcm(int, int, int)
를 사용하여 두 분모의 최소공배수를 분모deno
에 저장한다.
통분을 수행한 후에 두 분자를 더하면 되는데, 이 때 분모를 통분하는 과정에서 분모에 곱해진 수만큼 분자에도 곱해줘야 하므로 분자nume
에분자 * 분모에 곱해진 수(= 최소공배수 / 분모)
를 수행한 분자들의 합을 저장한다.
마지막으로 합 연산을 수행한 분자, 분모의 최대공약수gcd
를 구하여 분자, 분모를 각각 나눠주면 더 이상 약분되지 않는 기약분수가 된다.
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
st = new StringTokenizer(br.readLine());
int c = Integer.parseInt(st.nextToken());
int d = Integer.parseInt(st.nextToken());
int deno = lcm(b, d, gcd(Math.max(b, d), Math.min(b, d))); // 분모 : 최소공배수
int nume = (a * (deno/b)) + (c * (deno/d)); // 분자 합
int gcd = gcd(deno, nume); // 분자, 분모의 최대공약수
bw.write((nume/gcd) + " " + (deno/gcd)); // 기약분수 출력
br.close();
bw.close();
}
static int gcd(int x, int y) { // 최대공약수
int z = x % y;
if(z == 0) return y;
return gcd(y, z);
}
static int lcm(int a, int b, int gcd) { // 최소공배수
return (a/gcd) * (b/gcd) * gcd;
}
}