#include<iostream>
#include<cassert>
using namespace std;
class FractionType
{
public:
void Initialize(int num, int den);
FractionType Add(FractionType second);
FractionType Sub(FractionType second);
FractionType Mult(FractionType second);
FractionType Div(FractionType second);
void Reduction();
void Print();
int gcd(int m, int n);
int lcm(int m, int n);
private:
int num;
int den;
};
int main()
{
FractionType bunsu1, bunsu2, result_bunsu;
int bunja, bunmo;
int pre_bunja, pre_bunmo;
cout << "분수 계산기" << endl;
cout << "음수인 분수를 입력하시려면 분자에다가 음수 입력 요망" << endl;
cout << "분모에 0을 넣으면 오류 발생" << endl;
cout << "2개의 분수를 분자, 분모 순으로 입력해주세요 :";
cin >> bunja >> bunmo;
pre_bunja = bunja;
pre_bunmo = bunmo;
bunsu1.Initialize(bunja, bunmo);// 분수 1개 입력완료, 초기 내용 설정
//뒤의 입력을 통해 새로 입력받는 값에의해 분수 1의 분자 분모가 삭제되므로 다른 변수에 입력값을 저장해놓는다.
bunsu1.Print(); // initialize에 입력한 분수를 출력(bunsu1.initialize에 초기화된값은 첫번째 분수의 분자, 분모이다.)
cin >> bunja >> bunmo; // 분수 2의 분자, 분모 입력<전의 분수 1의 값은 입력으로 사라짐>
bunsu2.Initialize(bunja, bunmo); //두번째 분수 입력완료, 초기 내용 설정
cout << "+";
bunsu2.Print();//initialize에 입력한 분수를 출력(bunsu2.initialize에 초기화된값은 두번째 분수의 분자, 분모이다.)
cout << "=";
result_bunsu = bunsu1.Add(bunsu2); //계산식 연산<첫번째분수는 private의 저장된값으로, 두번째분수는 인자로써 들어가 연산>
result_bunsu.Reduction();
result_bunsu.Print();
bunsu1.Initialize(bunja, bunmo); // 분수 1개 입력완료, 초기 내용 설정
bunsu1.Print(); // initialize에 입력한 분수를 출력(bunsu1.initialize에 초기화된값은 첫번째 분수의 분자, 분모이다.)
bunsu2.Initialize(bunja, bunmo); //두번째 분수 입력완료, 초기 내용 설정
cout << "-";
bunsu2.Print();//initialize에 입력한 분수를 출력(bunsu2.initialize에 초기화된값은 두번째 분수의 분자, 분모이다.)
cout << "=";
result_bunsu = bunsu1.Sub(bunsu2);
result_bunsu.Reduction();
result_bunsu.Print();
cout << endl;
bunsu1.Initialize(bunja, bunmo); // 분수 1개 입력완료, 초기 내용 설정
bunsu1.Print(); // initialize에 입력한 분수를 출력(bunsu1.initialize에 초기화된값은 첫번째 분수의 분자, 분모이다.)
bunsu2.Initialize(bunja, bunmo); //두번째 분수 입력완료, 초기 내용 설정
cout << "*";
bunsu2.Print();//initialize에 입력한 분수를 출력(bunsu2.initialize에 초기화된값은 두번째 분수의 분자, 분모이다.)
cout << "=";
result_bunsu = bunsu1.Mult(bunsu2);
result_bunsu.Reduction();
result_bunsu.Print();
cout << endl;
bunsu1.Initialize(bunja, bunmo); // 분수 1개 입력완료, 초기 내용 설정
bunsu1.Print(); // initialize에 입력한 분수를 출력(bunsu1.initialize에 초기화된값은 첫번째 분수의 분자, 분모이다.)
bunsu2.Initialize(bunja, bunmo); //두번째 분수 입력완료, 초기 내용 설정
cout << "/";
bunsu2.Print();//initialize에 입력한 분수를 출력(bunsu2.initialize에 초기화된값은 두번째 분수의 분자, 분모이다.)
cout << "=";
result_bunsu = bunsu1.Div(bunsu2);
result_bunsu.Reduction();
result_bunsu.Print();
return 0;
}
void FractionType::Initialize(int input_num, int input_den) //Initialize : 초기 내용 설정, 수를 입력받은 것을 class의 private의 num, den에 저장
{
num = input_num;
den = input_den;
}
FractionType FractionType::Add(FractionType second){
FractionType result_bunsu;
result_bunsu.num = (num * second.den) + (second.num * den);
result_bunsu.den = lcm(den, second.den);
return result_bunsu;
}
FractionType FractionType::Sub(FractionType second){
FractionType result_bunsu;
result_bunsu.num = (num * second.den) - (second.num * den);
result_bunsu.den = lcm(den, second.den);
return result_bunsu;
}
FractionType FractionType::Mult(FractionType second){
FractionType result_bunsu;
result_bunsu.num = num* second.num;
result_bunsu.den = den*second.den;
return result_bunsu;
}
FractionType FractionType::Div(FractionType second){
FractionType result_bunsu;
result_bunsu.num = num*second.den;
result_bunsu.den = den*second.num;
return result_bunsu;
}
void FractionType::Reduction()
{
gcd(num, den);
num = num / gcd(num, den);
den = den / gcd(num, den);
}
void FractionType::Print()
{
if (den != 1){
cout <<"("<< num << "/" << den <<")";
}
else
{
cout << num;
}
}
int FractionType::gcd(int m, int n) {
if (n > m) // 최대공약수 통분할때 뒷수가 앞수보다 크면 자리 배치 바꿈, 손으로 쓰는 통분은 앞수가 작아도 되는데 이 방법은 좀 상이해서 바꿔줘야한다.
{
int temp;
temp = n;
n = m;
m = temp; // 자리를 바꾸었다.
if (m == 0){ // 중첩 if문 만약 gcd에 0이들어오면<그럴일은 없겠지만...> 그냥 n이 최대공약수
return n;
}
else // 0이아니면
{
return gcd(m, n%m);
}
}
else
{
if (m == 0)
return n;
else
return gcd(m, n%m);
}
}
int FractionType::lcm(int m, int n)
{
assert(m>0 && n>0);
int m1 = m / gcd(m, n); // 최소공배수 통분했을때 나오는 최대공약수 제외한 나머지 값
int n1 = n / gcd(m, n);
return gcd(n, m) * m1 * n1; // 최대 공약수 랑 통분했을 시 나오는 수들의 곱셈
}