Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

С++ Как осуществить сокращение дроби?

...МАРИНА... Ученик (198), закрыт 8 лет назад
Создайте класс Fraction (обыкновенная дробь), включающего поля: числитель, знаменатель. Реализовать методы сокращения дроби, возведения дроби в степень и вывод дроби. Перегрузить операции сложения, вычитания дробей.
Проблема с сокращением дробей, понимаю, что надо найти нод числит и знамен, но как это все устроить не понимаю, помогите пожалуйста!

#include
#include

class fraction
{
public:
int chisl;
int znamen;

int nod(int chisl, int znamen)
{
chisl=abs(chisl),znamen=abs(znamen);
if (znamen == 0)return chisl;
else return nod(znamen, chisl%znamen);
}

void define ( int ch=0, int zn=0)//определить значение дроби
{chisl=ch; znamen=zn;}
void display(void) //вывести на экран
{
cout<<"chisl= "<<chisl;
cout<< ", znamen= "<<znamen<<endl;
}
fraction operator+(const fraction&);
fraction operator-(const fraction&);
fraction sokr();
fraction stepen();
};

fraction fraction::operator+(const fraction& other) // +
{
fraction c;
c.define();
c.chisl=chisl*other.znamen+znamen*other.chisl;
c.znamen=znamen*other.znamen;
return c;
}

fraction fraction::operator-(const fraction& other) // -
{
fraction d;
d.define();
d.chisl=chisl*other.znamen-znamen*other.chisl;;
d.znamen=znamen*other.znamen;
return d;
}

fraction fraction::sokr()// сокращение дроби
{
fraction k;
k.define();
k.chisl=chisl%nod();
k.znamen=znamen%nod();
return k;
}
fraction fraction::stepen()// возведение в степень
{
fraction s;
s.define();
s.chisl=pow(chisl,2);
s.znamen=pow(znamen,2);
return s;
}

void main()
{
fraction a,b,c,d,k,s;
a.define(4,12);
b.define(1,3);
a.display();
b.display();
c=a+b;
c.display();
d=a-b;
d.display();
k=a.sokr();
k.display();
s=b.stepen();
s.display();
}
Лучший ответ
Constantine Мыслитель (9729) 8 лет назад
Не особо вникал в предложенный алгоритм, тем более, в вопросе не говорится, где ошибка и что выдаётся, а просто предлагаю свой вариант вычисления нод без рекурсии, т. к. злоупотреблять рекурсией не стоит, это всегда дополнительная нагрузка на стек.

===
#include <stdlib.h&gt

int nod(int a, int b)
{
// Чтоб случайно не попал туда 0,
// для инициализации годится любое ненулевое число.
int mod=1;

if(a==0 && b==0)
return 0; // Ошибка

// Подготовительные действия:
a=abs(a);
b=abs(b);

// Частные случаи:
if(a==b)
return a;
if(b>a)
{ mod=a; a=b; b=mod; }
if(b==0)
return a;

// Основной алгоритм, рекурсия, может, выглядит красивее,
// зато мы не расходуем напрасно пространство в стеке,
// в отличие от рекурсивных вызовов:
while(mod)
{
mod=a%b;
if(mod)
{
a=b;
b=mod;
}
}
return b;
}
Остальные ответы
Haskell Curry Мастер (1071) 8 лет назад
void define ( int ch=0, int zn=0)
Для этого конструкторы используются.

fraction fraction::sokr()
При сокращении числитель и знаменатель делят на НОД.
И почему создаётся новый объект? Не подразумевается ли, что текущая дробь должна упрощаться?
И сокращать дробь наверное надо после каждой операции сложения/вычитания.
...МАРИНА...Ученик (198) 8 лет назад
ну я хочу вывести сначала саму дробь ( не сокращенную), а потом измененную,
да, желательно чтоб все сокращалось, только как это сделать не могу понять,
int nod(int chisl, int znamen)
{
chisl=abs(chisl),znamen=abs(znamen);
if (znamen == 0)return chisl;
else return nod(znamen, chisl%znamen);
}
это вообще правильно? нужно это?
Haskell Curry Мастер (1071) Да вроде правильно.
Илья Ш Просветленный (20880) 8 лет назад
конструктор добавь )
fraction fraction::sokr()// сокращение дроби
{
int nod=this->nod();
this->chisl=this->chisl/nod;
this->znamen=this->znamen/nod;

}
...МАРИНА...Ученик (198) 8 лет назад
почему то в 0 обращаются числ и знамен)
Илья Ш Просветленный (20880) знач что то не так где то написано )
Батаев Дмитрий Просветленный (23021) 8 лет назад
Введи проверку знаменателя на ноль, иначе дроби такой быть не может, ну и поиск наименьшего общего делителя путём перебора деления без остатка числителя и знаменателя на числа от 2 до N разумного. может есть готовые алгоритмы...
Похожие вопросы