КИТА unofficial
Май 22, 2024, 12:13:14 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
Новости:
 
   Начало   ПРАВИЛА Помощь WIKI PDA Войти Регистрация  


Страниц: 1 [2] 3  Все   Вниз
  Печать  
Автор Тема: Искусство программиования (задача 6)  (Прочитано 31955 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Sochin
Злой модератор
Декан
*****

Карма: +108/-6
Offline Offline

Пол: Мужской
Сообщений: 1518



« Ответ #20 : Июль 24, 2007, 10:58:27 »

Поставил Билдер...Как-то он не по понятиям с исключениями работает... )))
Ушел читать стандарт С++. )))
Записан

Говорят, когда компьютер сгорает, перед взором микропроцессора за долю секунды проносятся все операции, которые он когда-либо совершил...
壯鎭
Sochin
Злой модератор
Декан
*****

Карма: +108/-6
Offline Offline

Пол: Мужской
Сообщений: 1518



« Ответ #21 : Июль 24, 2007, 06:55:48 »

Итак, по результатам сегодняшнего мини-исследования можно констатитровать:
1) В консольном не-VCL проекте на Билдере блок
Код:
catch(...)
не реагирует на исключения при делении на ноль, что противоречит стандарту С++.
Подозреваю, что это связано с реализацией VCL-класса исключения EDivByZero еще на объектном Паскале в Дельфи, откуда она была импортирована в Билдер.
Соотвественно, в коде
Код:
int a = 10, b =0;
try
{
double dd = a/b;
}
catch(...)
{
//
}
исключение при делении не будет перехвачено и обработано, что приведет к аварийному завершению приложения. Так что в этом случае вопросы не ко мне, а к производителю компилятора.

2) Функция sqrt, будучи описанной и реализованной еще в библиотеке языке С, при ошибках в аргументе, связанных с областью определения функции не вызывает исключений. Соответственно, обработка подобных ошибок осуществляется не через механизм исключений, а через глобальную С-переменную errno.

Учитывая эти находки был написан новый мего-код на стандартном C++:

Код:
#include <vcl.h> // Только для Билдера, что связано с особенностями реализации классов-исключений.

#include<math>
#include<errno>
#include <algorithm>
#include <set>
#include <iostream>

using namespace std;

//---------------------------------------------------------------------------
void Err()
{
set<int, less<int> >  errors, current, result;

insert_iterator<set<int, less<int> > >  res_ins(result, result.begin());

errors.insert(EDOM);
current.insert(errno);

set_intersection(errors.begin(), errors.end(), current.begin(), current.end(), res_ins);

while(result.empty()) return;

errno = 0;
throw 10;
}
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
   int a;
   cout << "input a:  ";
   cin >> a;

   int b;
   cout << "input b: ";
   cin >> b;

   try
    {
        double dd = sqrt(a);
        Err();
    }
   catch(...)
    {
     //здесь  a < 0;
       try
         {
            double dd1 = sqrt(b);
            Err();
         }
       catch(...)
         {
           //здесь  a < 0 и b < 0
            int i = 1;

            while (1)
            {
              try
               {
                  double dd2 = a / (a + i);
               }
              catch(...)
               {
                  cout << a << " является максимальным из чисел";
                  return 1;
               }
              try
               {
                 double dd3 = b / (b + i);
               }
              catch(...)
               {
                  cout << b << " является максимальным из чисел";
                  return 1;
               }
               i++;
            }
         }
     //здесь  a < 0 и b >= 0
        cout << b << " является максимальным из чисел";
        return 1;
    }
    //здесь a >= 0
      try
      {
          double dd4 = sqrt(b);
          Err();
      }
     catch(...)
      {
        // здесь a >= 0 и b < 0
        cout << a << " является максимальным из чисел";
        return 1;
      }

    // здесь a >= 0 и b >= 0
    int j = 0;

    while (1)
    {
       try
       {
          double dd5 = a / (a - j);
       }
       catch(...)
       {
          cout << b << " является максимальным из чисел";
          return 1;
       }

       try
       {
          double dd6 = b / (b - j);
       }
       catch(...)
       {
          cout << a << " является максимальным из чисел";
          return 1;
       }
       j++;
   }
}

Кстати, компилятор MS Visual C++ .NET 2005 генерит код, который корректно ловит все исключения независимо от типа проекта. Вариант для MS Visual C++:

Код:
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
         int a = 0;
         int b = -5;

   try
    {
            while(double::IsNaN(System::Math::Sqrt(a))) throw gcnew Exception();
    }
   catch(...)
    {
     //здесь  a < 0;
       try
         {
              while(double::IsNaN(System::Math::Sqrt(b))) throw gcnew Exception();
         }
       catch(...)
         {
           //здесь  a < 0 и b < 0
            int i = 1;

            while (1)
            {
              try
               {
                   while(double::IsNaN(a / (a + i))) throw gcnew Exception();
               }
              catch(...)
               {
                       button1->Text = a.ToString()+" является максимальным из чисел";
                  return;
               }
              try
               {
                   while(double::IsNaN(b / (b + i))) throw gcnew Exception();
               }
              catch(...)
               {
                  button1->Text = b.ToString()+" является максимальным из чисел";
                  return;               
               }
               i++;
            }
         }
     //здесь  a < 0 и b >= 0
        button1->Text = b.ToString()+" является максимальным из чисел";
        return;
    }
    //здесь a >= 0
      try
      {
            while(double::IsNaN(System::Math::Sqrt(b))) throw gcnew Exception();
      }
     catch(...)
      {
        // здесь a >= 0 и b < 0
        button1->Text = a.ToString()+" является максимальным из чисел";
        return;
      }

    // здесь a >= 0 и b >= 0
    int j = 0;

    while (1)
    {
       try
       {
            while(double::IsNaN( a / (a - j))) throw gcnew Exception();
       }
       catch(...)
       {
          button1->Text = b.ToString()+" является максимальным из чисел";
          return;
       }

       try
       {
            while(double::IsNaN( b / (b - j) )) throw gcnew Exception();
       }
       catch(...)
       {
          button1->Text = a.ToString()+" является максимальным из чисел";
          return;
       }
       j++;
   }
}

Почувствуйте мощь и силу С++ с костылями для новой платформы .. )))

З.Ы. Спасибо товарищу BODROV-у за активную помощь в ловле блох. ))

Записан

Говорят, когда компьютер сгорает, перед взором микропроцессора за долю секунды проносятся все операции, которые он когда-либо совершил...
壯鎭
NunTerix
Декан
*****

Карма: +26/-1
Offline Offline

Пол: Мужской
Сообщений: 1688



« Ответ #22 : Июль 24, 2007, 06:58:05 »

Ёпсель как тут много ....
Записан

Сердце может прибавить ума, но ум не может прибавить сердца.
LazarusLong
Ирландский доброволец
Проректор
*****

Карма: +181/-7
Offline Offline

Пол: Мужской
Награды:
А может я тоже хочу себе награду?
Сообщений: 6133


Ukrainian by birth, Irish by the grace of God


WWW
« Ответ #23 : Июль 24, 2007, 08:06:05 »

Кто еще не оптимальнее напишет? Смеющийся
Sochin, ладно, идея ясна и имеет право на существование. Никаких требований к оптимальности я не предъявлял, посему +1 Подмигивающий.

Викторина продолжается. Есть еще один очень простой способ
Записан

Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.

"...Он любил говорить факин щит
Когда что-то не так ему
Принимал он свой самый ирландский вид
И кидался трубкой в жену..."
Sochin
Злой модератор
Декан
*****

Карма: +108/-6
Offline Offline

Пол: Мужской
Сообщений: 1518



« Ответ #24 : Июль 24, 2007, 10:16:48 »

Кто еще не оптимальнее напишет? Смеющийся
Полагаешь неоптимально использование для организации ветвлений исключений в принципе? Какие другие варианты для ветвлений без использования условных операторов? ))) Самое неоптимально в последнем варианте это сравнение кода ошибки через пересечение множеств, тут уж увы поделать нечего. )))

Цитировать
Викторина продолжается. Есть еще один очень простой способ
Очень интересно глянуть на решение. Надеюсь этот способ относится больше к области программирования, а не математики как первое решение в этом топе. )
Записан

Говорят, когда компьютер сгорает, перед взором микропроцессора за долю секунды проносятся все операции, которые он когда-либо совершил...
壯鎭
tendervampire
Бакалавр
**

Карма: +12/-0
Offline Offline

Пол: Мужской
Сообщений: 112


П.Б.Н.


« Ответ #25 : Июль 24, 2007, 10:31:28 »

Касательно сомнений в возможности прикрутить циклы. Как вариант:
Код:
void main()
{
 int a,b,r;
 printf ("Введите первое целочисленное число ");
   scanf ("%d", &a);
   printf ("Введите первое целочисленное число ");
   scanf ("%d", &b);
   r = abs(a-b);
   
   while(r+a-b)
   {
   printf("%3d",a);
   break;
   }

   while(r+b-a)
   {
   printf("%3d",b);
   break;
   }
scanf;
}
Надеюсь, обвинений в плагиате не последует Улыбка
Записан

- Our arrows will blind out the sun
 - Then we will fight in the shade!
LazarusLong
Ирландский доброволец
Проректор
*****

Карма: +181/-7
Offline Offline

Пол: Мужской
Награды:
А может я тоже хочу себе награду?
Сообщений: 6133


Ukrainian by birth, Irish by the grace of God


WWW
« Ответ #26 : Июль 24, 2007, 11:49:43 »

tendervampire
Да, насчет циклов я погорячился. Хотя это просто по сути замена для if - цикл выполняющийся один раз. Да и этот код не будет работать если a и b равны - оба условия циклов равны 0.

Sochin, первое решение, приведенное NunTerix'ом - по видимому самое оптимальное. По крайней мере оно оптимальнее моего. Что же твоего решения - то оно является не оптимальным для решения данной конкретной задачи. Для других случаев подобный подход может быть оптимальным, не спорю. Все зависит от задачи. Если хочешь, кстати, могу в ЛС тебе написать свой вариант. Здесь открывать пока не хочется Подмигивающий.



Записан

Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.

"...Он любил говорить факин щит
Когда что-то не так ему
Принимал он свой самый ирландский вид
И кидался трубкой в жену..."
tendervampire
Бакалавр
**

Карма: +12/-0
Offline Offline

Пол: Мужской
Сообщений: 112


П.Б.Н.


« Ответ #27 : Июль 25, 2007, 02:04:22 »

 
Уважаемый LazarusLong!
   При условии равенства А и Б действительно не происходит никаких действий, но в условии задачи ничего не сказано о равенстве. Прикрутить проверку равенста - сложности не представляет. То, что в данном случае while работает как if не является нарушением условий задачи. Как говорится, в умелых руках...
 
P.S. Сколько раз зарекался не работать без подписанного тех.задания Улыбка .
Записан

- Our arrows will blind out the sun
 - Then we will fight in the shade!
LazarusLong
Ирландский доброволец
Проректор
*****

Карма: +181/-7
Offline Offline

Пол: Мужской
Награды:
А может я тоже хочу себе награду?
Сообщений: 6133


Ukrainian by birth, Irish by the grace of God


WWW
« Ответ #28 : Июль 25, 2007, 06:04:23 »

Да ничего против я не имею. Просто считаю, что если, к примеру, в последовательности все элементы равны, это на значит, что в ней нет максимального значения. Просто оно(значение) в таком случае совпадает с минимальным;).

А насчет циклов - мне сложно было представить как их использовать в этой задаче в своей первоначальной цели - организации повторяющихся вычислений в программе. Хотя подумав немного придумал Подмигивающий.

Код:
int a=10, b=5;
int a1, a2;
a1 = a;
a2 = a;
while((b-a1--)&&(b-a2++));
while(!(b-a1-1))
{
cout<<a;
        exit(0);
}
cout<<b;

Не пробовал это запускать, но по идее должно работать Подмигивающий. Зато здесь цикл как цикл - выполняет повторяющиеся действия Подмигивающий Подмигивающий Подмигивающий. Вот в каком смысле я не представлял использование циклов Подмигивающий. Но, как известно, было бы желание, можно и гвозди микроскопом забивать Подмигивающий.
Записан

Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.

"...Он любил говорить факин щит
Когда что-то не так ему
Принимал он свой самый ирландский вид
И кидался трубкой в жену..."
tendervampire
Бакалавр
**

Карма: +12/-0
Offline Offline

Пол: Мужской
Сообщений: 112


П.Б.Н.


« Ответ #29 : Июль 25, 2007, 12:09:06 »

  Начинает происходит типичное для невербального общения непонимание Улыбка
Это, конечно, похоже на флуд, но вот варинт с проверкой равенства:
Код:
void main()
{
 int a,b,r;
 printf ("Введите первое целочисленное число ");
   scanf ("%d", &a);
   printf ("Введите первое целочисленное число ");
   scanf ("%d", &b);
   r = abs(a-b);
   
   while(r+a-b)
   {
   printf("%3d",a);
   getch();
   return a;
   }

   while(r+b-a)
   {
   printf("%3d",b);
   getch();
   return b;
   }
   printf("Значения одинаковы a и b: %3d",a);
getch();
return a;
}


Принцип вычисления для последовательностей с l>2 - как для вычисления НОК.
Схематично:
Код:
  int Max(int a,int b)
   {
     // сюда пишем то, что выше
    }
    int mas[10];
 a = mas[0];
for(int i=1;i<10;i++)
a = Max(a,mas[i])
return a;

 Безусловно, вариант не оптимальный. Вариант NunTerix'a куда лучше. Но с if не сравнить Смеющийся
 Насчет применения в реальной жизни - если мне придется писать на языке, который будет похож на указанный в задании, я с создателем языка сделаю что-нибудь плохое томиком Стауструпа Улыбка
 А насчет гвоздей и микроскопа - всякое в жизни бывает, вдруг, забивание гвоздя - дело жизни  и смерти Улыбка
Записан

- Our arrows will blind out the sun
 - Then we will fight in the shade!
LazarusLong
Ирландский доброволец
Проректор
*****

Карма: +181/-7
Offline Offline

Пол: Мужской
Награды:
А может я тоже хочу себе награду?
Сообщений: 6133


Ukrainian by birth, Irish by the grace of God


WWW
« Ответ #30 : Июль 25, 2007, 05:43:30 »

Ладно. Замнем для ясности. +1.

Насчет языка. Дык без ограничений сильно просто было бы и не интересно Подмигивающий. Ясное дело, что на таком языке без условных операторов и всего прочего вряд ли придется писать Подмигивающий

Кстати мне сегодня пришла в голову еще одна идея как можно решить данную задачу. Как то обыграть ситуацию, что а/b = 0 если а меньше b и не 0 в противном случае. Правда, будет работать только для а>=0, b>0.
Записан

Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.

"...Он любил говорить факин щит
Когда что-то не так ему
Принимал он свой самый ирландский вид
И кидался трубкой в жену..."
tendervampire
Бакалавр
**

Карма: +12/-0
Offline Offline

Пол: Мужской
Сообщений: 112


П.Б.Н.


« Ответ #31 : Июль 25, 2007, 06:59:10 »

 Интересно, можно подумать. b==0 можно отловить exception'ом. А +/- можно отловить опять же while( znach+abs(znach)) Смеющийся. Но в итоге получается самый неоптимальный вариант из всех представленных Улыбка)) А для неотрицательных - очень даже симатично.
Записан

- Our arrows will blind out the sun
 - Then we will fight in the shade!
naxellar
Главный флудер
Проректор
*****

Карма: +101/-52
Offline Offline

Пол: Мужской
Сообщений: 5015

Главный флудер


« Ответ #32 : Июль 26, 2007, 01:32:37 »

Загляни в какой нибудь справочник по С и скажи мне какая функция абсолютного значения?
abs, fabs, etc. Причем fabs для вещественных чисел, которыми тут и не пахнет
Записан
NunTerix
Декан
*****

Карма: +26/-1
Offline Offline

Пол: Мужской
Сообщений: 1688



« Ответ #33 : Июль 26, 2007, 09:15:40 »

fabs - только для вещественных чисел? Шокирован
Записан

Сердце может прибавить ума, но ум не может прибавить сердца.
naxellar
Главный флудер
Проректор
*****

Карма: +101/-52
Offline Offline

Пол: Мужской
Сообщений: 5015

Главный флудер


« Ответ #34 : Июль 26, 2007, 09:19:33 »

fabs - только для вещественных чисел? Шокирован
Не думаю, что только, но она не нужна так как есть обычная abs (Я так понял)
Записан
tendervampire
Бакалавр
**

Карма: +12/-0
Offline Offline

Пол: Мужской
Сообщений: 112


П.Б.Н.


« Ответ #35 : Июль 26, 2007, 12:06:55 »

 По результату, abs и fabs идентичны. Просто abs в чистом с отсутствует. А с++ без разницы, что использовать.
Записан

- Our arrows will blind out the sun
 - Then we will fight in the shade!
NunTerix
Декан
*****

Карма: +26/-1
Offline Offline

Пол: Мужской
Сообщений: 1688



« Ответ #36 : Июль 26, 2007, 05:18:20 »

По результату, abs и fabs идентичны. Просто abs в чистом с отсутствует.

Ну вот .... а писалось, предполагая, что только на С ... так что naxellar нужна ....
Записан

Сердце может прибавить ума, но ум не может прибавить сердца.
LazarusLong
Ирландский доброволец
Проректор
*****

Карма: +181/-7
Offline Offline

Пол: Мужской
Награды:
А может я тоже хочу себе награду?
Сообщений: 6133


Ukrainian by birth, Irish by the grace of God


WWW
« Ответ #37 : Июль 26, 2007, 07:12:38 »

abs есь и в С. Вернее в Сишном math.h - есть функция abs со следующим прототипом:
int abs(int).
Кроме того:
double fabs(double)
long labs(long)
и еще для комплексных чисел Подмигивающий
Записан

Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.

"...Он любил говорить факин щит
Когда что-то не так ему
Принимал он свой самый ирландский вид
И кидался трубкой в жену..."
Sochin
Злой модератор
Декан
*****

Карма: +108/-6
Offline Offline

Пол: Мужской
Сообщений: 1518



« Ответ #38 : Июль 26, 2007, 07:19:57 »

Я не пойму из-за чего весь спор? Тип int приводится к типу double, так что вариант fabs годится. )
Записан

Говорят, когда компьютер сгорает, перед взором микропроцессора за долю секунды проносятся все операции, которые он когда-либо совершил...
壯鎭
LazarusLong
Ирландский доброволец
Проректор
*****

Карма: +181/-7
Offline Offline

Пол: Мужской
Награды:
А может я тоже хочу себе награду?
Сообщений: 6133


Ukrainian by birth, Irish by the grace of God


WWW
« Ответ #39 : Июль 26, 2007, 07:36:37 »

То что int приводится к double это ясно. А double приводится к int? Ведь в варианте NunTerix'a нужно как раз именно такое приведение.
Записан

Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.

"...Он любил говорить факин щит
Когда что-то не так ему
Принимал он свой самый ирландский вид
И кидался трубкой в жену..."
Страниц: 1 [2] 3  Все   Вверх
  Печать  
 
Перейти в:  

Penguins Counter Powered by MySQL Powered by PHP Powered by SMF 1.1.8 | SMF © 2006-2008, Simple Machines LLC Valid XHTML 1.0! Valid CSS! Internetmap
Страница сгенерирована за 0.103 секунд. Запросов: 32.