Re: pешаем системy методом Гаyсса

From
Andrew Ezhguroff ()
To
Graf Alex
Date
2002-10-25T19:53:41Z
Area
RU.ALGORITHMS
From: "Andrew Ezhguroff" <eandr@com2com.ru>

Привет! "Graf Alex" <Graf.Alex@f436.n463.z2.fidonet.org>  сообщил(а):

 GA> //Стpyктypа, опpеделяющая пpавильнyю дpобь
 GA> typedef struct{
 GA>   long chisl, znam;
 GA> } drob;

Раз у тебя С++, то почему бы не использовать класс с нормальными
конструкторами?

 GA> //Фyнкция, котоpая сокpащает дpобь до пpиемлимого вида
 GA> drob sokr(drob a)
 GA> {
 GA>   while((a.chisl%2==0)&&(a.znam%2==0))
 GA>   {
 GA>     a.chisl/=2;
 GA>     a.znam/=2;
 GA>   }
 GA>
 GA>   int b=3;
 GA>   int min;
 GA>   if(abs(a.chisl)>abs(a.znam))
 GA>     min=abs(a.znam);
 GA>   else
 GA>     min=abs(a.chisl);
 GA>
 GA>   while(b<=min)
 GA>   {
 GA>     while((a.chisl%b==0)&&(a.znam%b==0))
 GA>     {
 GA>       a.chisl/=b;
 GA>       a.znam/=b;
 GA>     }
 GA>     b+=2;
 GA>   }
 GA>
 GA>   if(a.chisl==0)
 GA>     a.znam=1;
 GA>
 GA>   return a;
 GA> }

Пожалуй, самый странный вариант сокращения дробей, который я видел. :-)
Существует же стандартный алгоритм нахождения НОД.

long nod(long Val_1, long Val_2){
  if(Val_1<0)Val_1= -Val_1;
  if(Val_2<0)Val_2= -Val_2;
  if(Val_1<Val_2){
    long Tmp=Val_1;
    Val_1=Val_2;
    Val_2=Tmp;
  }
  while(Val_2!=0){
    long Tmp=Val_1%Val_2;
    Val_1=Val_2;
    Val_2=Tmp;
  }
  return Val_1;
}

drob sokr(drob a){
  if(a.chisl==0){
    a.znam=1;
  }else{
    long Tmp = nod(a.chisl, a.znam);
    a.chisl/=Tmp;
    a.znam/=Tmp;
  }
  return a;
}

 GA> drob getdrob(long a, long b)
 GA> {
 GA>   drob r;
 GA>   r.chisl=a;
 GA>   r.znam=b;
 GA>   return r;
 GA> }
 GA> drob getdrob(double a)
 GA> {
 GA>   drob r;
 GA>   double b;
 GA>   r.znam=1;
 GA>   while(modf(a, &b)!=0)
 GA>   {
 GA>     r.znam*=10;
 GA>     a*=10;
 GA>   }
 GA>   r.chisl=(long)b;
 GA>   return r;
 GA> }

Это должны быть не ф-ции, а конструкторы. К тому же ты забыл добавить вызовы
sokr (для обработки случаев типа getdrob(3, 15)).

 GA> drob abs(drob a)
 GA> {
 GA>   drob r;
 GA>   if(a.chisl<0)
 GA>     r.chisl=a.chisl*(-1);
 GA>   else
 GA>     r.chisl=a.chisl;
 GA>
 GA>   if(a.znam<0)
 GA>     r.znam=a.znam*(-1);
 GA>   else
 GA>     r.znam=a.znam;
 GA>
 GA>   return r;
 GA> }

Во первых, дико смотрится умножение на -1, когда в языке существует операция
изменения знака.
Во вторых, операции должны быть реализованы так, чтобы знаменатель всегда
был больше 0.

 GA> {
 GA>   drob r;
 GA>   r.chisl=a.chisl*b.chisl;
 GA>   r.znam=a.znam*b.znam;
 GA>
 GA>   r=sokr(r);
 GA>   return r;
 GA> }

При наличии вышеупомянутого конструктора это было бы записано как:

{
  return drob(a.chisl*b.chisl, a.znam*b.znam);
}

И даже в твоем случае можно написать:

{
  return getdrob(a.chisl*b.chisl, a.znam*b.znam);
}


 GA> int operator>(drob a, drob b)
 GA> {
 GA>   if (a.chisl>b.chisl)
 GA>     return 1;
 GA>   else
 GA>     return 0;
 GA> }

А здесь просто ошибка: что выдаст твоя операция при сравнении 2/3 и 3/7?

С уважением, Андрей.


-- 
Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru
--- ifmail v.2.15dev5
 * Origin: Talk.Mail.Ru (2:5020/400)