분수(Fraction) 사칙연산하기 (struct 사용)

c++ 언어 사용

 

 

 

문제 : 

구조체(struct)를 이용해서 분수값들간의 사칙연산(Operations with Fractions)을 수행하는 함수를 구현하라. 

 

 

 

조건 :

1. 구조체(struct)를 사용한다.
2. 두 값의 사칙연산(덧셈, 뺄셈, 곱셈, 나눗셈)에 대한 각 함수를 구현한다.
3. 두 값의 비교연산을 하는 함수를 구현한다.

 

 

 

풀이 코드 :

#include<iostream>
using namespace std;

typedef struct Fraction{
	int bunja;
	int bunmo;
}Fraction;

Fraction addFraction(Fraction x, Fraction y);
Fraction subFraction(Fraction x, Fraction y);
Fraction multFraction(Fraction x, Fraction y);
Fraction divFraction(Fraction x, Fraction y);
bool compare(Fraction x, Fraction y);
void trimFraction(Fraction &x);

int main(){
	Fraction a,b,c;
	bool bi;

	a.bunja=3, a.bunmo=5;
	b.bunja=3, b.bunmo=9;

	printf("a = %d / %d\n", a.bunja, a.bunmo);
	printf("b = %d / %d\n\n", b.bunja, b.bunmo);

	trimFraction(c = addFraction(a,b));
		printf("더하기\t%d / %d\n", c.bunja, c.bunmo);
	trimFraction(c = subFraction(a,b));
		printf("빼기\t%d / %d\n", c.bunja, c.bunmo);
	trimFraction(c = multFraction(a,b));
		printf("곱하기\t%d / %d\n", c.bunja, c.bunmo);
	trimFraction(c = divFraction(a,b));
		printf("나누기\t%d / %d\n", c.bunja, c.bunmo);

	bi = compare(a,b);
	if(bi==1)
		printf("비교(큰 수) = %d / %d\n", a.bunja, a.bunmo);
	else	
		printf("비교(큰 수) = %d / %d\n", b.bunja, b.bunmo);

	return 0;
}
Fraction addFraction(Fraction x, Fraction y){
	Fraction z;
	z.bunmo = x.bunmo * y.bunmo;
	z.bunja = y.bunmo * x.bunja + x.bunmo * y.bunja;
	return z;
}
Fraction subFraction(Fraction x, Fraction y){
	Fraction z;
	z.bunmo = x.bunmo * y.bunmo;
	z.bunja = y.bunmo * x.bunja - x.bunmo * y.bunja;
	return z;
}
Fraction multFraction(Fraction x, Fraction y){
	Fraction z;
	z.bunmo = x.bunmo * y.bunmo;
	z.bunja = y.bunja * x.bunja;
	return z;
}
Fraction divFraction(Fraction x, Fraction y){
	Fraction z;
	z.bunmo = x.bunmo * y.bunja;
	z.bunja = y.bunmo * x.bunja;
	return z;
}
bool compare(Fraction x, Fraction y){
	if(y.bunmo * x.bunja - x.bunmo * y.bunja > 0)
		return 1;
	else
		return 0;
}
void trimFraction(Fraction &x){
	int down = x.bunja, up = x.bunmo, com;
	if(x.bunja > x.bunmo){
		down = x.bunmo;
		up = x.bunja;
	}

	for(int i=1; i<=down; i++)
		if((down%i)==0 && (up%i)==0)
			com=i;

	x.bunja/=com;
	x.bunmo/=com;
}

 

 

 

실행 결과 : 

a = 3 / 5
b = 3 / 9

더하기  14 / 15
빼기    4 / 15
곱하기  1 / 5
나누기  9 / 5
비교(큰 수) = 3 / 5

 

 

 

풀이 설명 :

사칙연산 및 비교 연산을 수행하는 함수들은 통분을 사용해서 어렵지 않게 구현할 것이라고 생각한다. 주어진 조건대로 모두 구현하면 아래와 같은 함수들이 구현될 것이다.

 

  • Fraction addFraction(Fraction x, Fraction y) : 두 분수값의 덧셈 함수
  • Fraction subFraction(Fraction x, Fraction y) : 두 분수값의 뺄셈 함수
  • Fraction multFraction(Fraction x, Fraction y) : 두 분수값의 곱셈 함수
  • Fraction divFraction(Fraction x, Fraction y) : 두 분수값의 나눗셈 함수
  • bool compare(Fraction x, Fraction y) : 두 분수값의 크기비교 함수
  • void trimFraction(Fraction &x) : 분수값을 (최대공약수로) 약분하는 함수

 

이 문제를 해결할 때 고려해야하는 점은 최대공약수(GCD)이다. 여기서 최대공약수를 사용하는 이유는 통분을 이용한 사칙연산을 수행한 이후에 나온 결과값에 대해 약분이 필요한 경우가 존재하기 때문이다. 따라서 위처럼 trimFraction 함수를 추가로 만들어준 것이다.

 

예를 들어, 위 풀이코드에서 덧셈을 생각해보자. 3/5 + 3/9를 계산할 때 분모를 통분해서 계산하면 42/45의 값이 나올 것이다. 하지만 이 결과값을 그대로 최종 결과로 출력하는 것보다는 약분이 가능하다면 약분까지 연산된 최종 결과값을 출력시켜주는 것이 깔끔할 것이다. 분자값인 42와 분모값인 45의 최대공약수인 3으로 약분하면 최종 결과값은 14/15가 된다.