Решение задачи Дробная арифметика с Меньшиков

Без пояснения   Просмотров: 64


Напишите программу, реализующую сложение, вычитание, умножение и деление дробей. Формат дробей во входных и выходных данных:

знак числа (пишется только в случае, когда его отсутствие изменяет число);
целая часть числа (нулевая целая часть не пишется, если есть числитель и знаменатель);
пробел (не пишется, если отсутствует целая или дробная часть);
числитель (если он не равен нулю);
знак / (если есть числитель);
знаменатель (если есть числитель).
Примеры представления дробных чисел: -7 3/4, 8 1/2, -7/11, 0, 11.

Ограничения (как на входные, так и на выходные данные): целая часть может принимать значения из диапазона 0...30 000, числитель и знаменатель могут принимать значения от 1 до 30 000, при делении второй операнд не равен нулю.

Код

#include <iostream>
#include <cstdio>
#include <string>
 
using namespace std;
 
int abs(int a)
{
    if (a<0)
        return -a;
    return a;
}
int gcd(int a, int b)
{
    return b ? gcd(b,a%b) : a;
}
int lcm(int a, int b)
{
    return a * b / gcd(a,b);
}
struct fraction
{
    int numer; // числитель
    int denom; // знаменатель
    fraction()
    {
        numer = 0;
        denom = 1;
    }
    fraction(int num, int den)
    {
        numer = num;
        denom = den;
        normir();
    }
    void normir()
    {
        int nod = gcd(numer, denom);
        numer /= nod;
        denom /= nod;
 
        if (denom < 0)
        {
            denom = -denom;
            numer = -numer;
        }
    }
    void input()
    {
        string str;
        getline(cin, str);
        int pos = str.find(' '); // отдельно дробная, и отдельно дробная
       
        if (pos!=-1)
        {
            string f = str.substr(0,pos);
            string s = str.substr(pos+1,str.size() - (pos+1));
           
            int cel;
            sscanf(f.c_str(),"%d", &cel);
            sscanf(s.c_str(),"%d/%d", &numer, &denom);
           
            if (denom * cel < 0)
                numer = -numer + denom * cel;
            else
                numer =  numer + denom * cel;
            normir(); // сокрощение дроби
        }
        else
        {
            pos = str.find('/');
            if (pos == -1)
                sscanf(str.c_str(), "%d", &numer);
            else
                sscanf(str.c_str(),"%d/%d", &numer, &denom);
            normir();
        }
    }
    void output()
    {
        if (denom == 1)
            cout<<numer;
        else
        {
            int cel = numer / denom;
            if (cel)
            {
                numer = abs(numer);
                printf("%d %d/%d",cel, numer%denom, denom);
            }
            else
                printf("%d/%d",numer, denom);
        }
    }
};
fraction operator + (const fraction &a, const fraction &b)
{
    int denom = lcm(a.denom, b.denom);
    int numer = denom / a.denom * a.numer +
                denom / b.denom * b.numer;
    return fraction(numer,denom);
}
fraction operator - (const fraction &a, const fraction &b)
{
    int denom = lcm(a.denom, b.denom);
    int numer = denom / a.denom * a.numer -
                denom / b.denom * b.numer;
    return fraction(numer,denom);
}
fraction operator * (const fraction &a, const fraction &b)
{
    int numer = a.numer * b.numer;
    int denom = a.denom * b.denom;
    return fraction(numer,denom);
}
fraction operator / (const fraction &a, const fraction &b)
{
    int numer = a.numer * b.denom;
    int denom = a.denom * b.numer;
    return fraction(numer,denom);
}
 
fraction a,b,c;
void solve()
{
    char oper;
    a.input();
    cin>>oper;
    cin.ignore();
    b.input();
    switch(oper)
    {
    case '+': c = a + b; break;
    case '-': c = a - b; break;
    case '*': c = a * b; break;
    case '/': c = a / b; break;
    }
    c.output();
   
}
int main()
{
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
 
    solve();
    return 0;
}

         

Администратор Photo Автор: Администратор



Комментарии

Чтобы написать комментарии вам нужно войти в систему или зарегистрироваться