2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 Найти среднее (С++)
Сообщение13.01.2019, 11:49 


06/04/18

323
Из трёх попарно неравных введённых пользователем целых чисел найти такое, которое не будет ни наибольшим, ни наименьшим.
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include <iostream>
using namespace std;

int abc(int x, int y)
{
    return (x==y)? 0 : 1;
}

int xyz(int x, int y, int z)
{
    if ((x<y && y<z)||(x>y && y>z)) return y;
    else if ((y<x && x<z)||(y>x && x>z)) return x;
    else return z;
}

int main()
{
    int a, b, c;
    point:
    cout << "Введите три попарно неравных целых числа:\n";
    cin >> a >> b >> c;
    if (abc(a,b)*abc(a,c)*abc(b,c)==0) {cout << "Введено неверно\n";
    goto point;}
    else cout << xyz(a,b,c);
}
Хорошее ли у меня получилось решение? Если нет, то как можно сделать лучше?

 Профиль  
                  
 
 Re: Найти среднее (С++)
Сообщение13.01.2019, 12:06 
Аватара пользователя


14/12/17
1532
деревня Инет-Кельмында
названия abc(), xyz() - почему не dura1(), dura2()?
abc() лучше бы проверял все три числа на равенство: return (x==y) || (x==z) || (y==z); - а не *, есть bool и есть || !!
xyz() можно упростить: if (x<y) return y<z ? y : z; else return x<z ? x : z;
или в одном стиле:
return x<y
? (y<z ? y : z)
: (x<z ? x : z);

 Профиль  
                  
 
 Re: Найти среднее (С++)
Сообщение13.01.2019, 12:12 
Заслуженный участник
Аватара пользователя


28/07/09
1238
Вызов функци abc(x, y) заменить конструкцией (x != y)

goto заменить на while.

Количество сравнений в основной функции явно можно уменьшить

 Профиль  
                  
 
 Re: Найти среднее (С++)
Сообщение13.01.2019, 12:17 


06/04/18

323
eugensk в сообщении #1368211 писал(а):
if (x<y) return y<z ? y : z;
Ну, проверьте случай z=1, x=2, y=3.

 Профиль  
                  
 
 Re: Найти среднее (С++)
Сообщение13.01.2019, 12:23 
Аватара пользователя


14/12/17
1532
деревня Инет-Кельмында
Qlin в сообщении #1368214 писал(а):
Ну, проверьте случай z=1, x=2, y=3.

отлично! я слишком упростил и ошибся, значит истина где-то посередине. У вас 8 сравнений в xyz(), у меня 3, мне кажется, что достаточно 5.

 Профиль  
                  
 
 Re: Найти среднее (С++)
Сообщение13.01.2019, 12:33 


06/04/18

323
Legioner93 в сообщении #1368213 писал(а):
goto заменить на while.
Я бы это сделал, но если условие цикла выполнено, надо как-то информировать юзера, что введенные значения не подходят.
eugensk в сообщении #1368217 писал(а):
У вас 8 сравнений в xyz(), у меня 3, мне кажется, что достаточно 5.
Legioner93 в сообщении #1368213 писал(а):
Количество сравнений в основной функции явно можно уменьшить
Видимо можно. Но я не придумал, как.

 Профиль  
                  
 
 Re: Найти среднее (С++)
Сообщение13.01.2019, 12:36 
Заслуженный участник
Аватара пользователя


28/07/09
1238
Пузырёк вручную и выводим второй элемент
Код:
#include <cstdio>                                                               
                                                                                                                                                               
int xyz(int x, int y, int z)                                                   
{                                                                               
    if(x > y) swap(x, y);                                                       
    if(y > z) swap(y, z);                                                       
    if(x > y) swap(x, y);                                                       
    return y;                                                                   
}

 Профиль  
                  
 
 Re: Найти среднее (С++)
Сообщение13.01.2019, 12:45 


27/08/16
11088
Это называется не "среднее", а "медиана".

 Профиль  
                  
 
 Re: Найти среднее (С++)
Сообщение13.01.2019, 12:47 
Аватара пользователя


14/12/17
1532
деревня Инет-Кельмында
Точно 5 сравений в коде:

Используется синтаксис C++
return x<y
         ? (y<z  
            ? y                 // x<y y<z
            : (x<z ? z : x))    // x<y z<y
         : (x<z
            ? x                 // y<x x<z
            : (y<z ? z : y));   // y<x z<x
 


Осуществляются или 2, или 3, эффективнее сделать уже не получится.

 Профиль  
                  
 
 Re: Найти среднее (С++)
Сообщение13.01.2019, 12:48 


06/04/18

323
Legioner93, да, этот вариант хорош. Спасибо.

Поскольку от goto принято избавляться, я перепишу определение функции main:
Используется синтаксис C++
int main()
{
    int a, b, c;
    cout << "Введите три попарно неравных целых числа:\n";
    cin >> a >> b >> c;
    while ((a==b)||(b==c)||(a==c))
    {
    cout << "Введено неверно\n";
    cout << "Введите три попарно неравных целых числа:\n";
    cin >> a >> b >> c;
    }
    cout << xyz(a,b,c);
}

 Профиль  
                  
 
 Re: Найти среднее (С++)
Сообщение13.01.2019, 12:54 
Заслуженный участник
Аватара пользователя


28/07/09
1238
Код:
int xyz(int x, int y, int z)                                                   
{                                                                               
    return max(min(x, y), min(max(x, y), z));                                   
}


-- Вс янв 13, 2019 13:05:19 --

Qlin
Можно избежать дублирования ввода и вывода, и при этом обойтись без goto

Код:
int main()                                                                     
{                                                                               
    int a, b, c;                                                               
    do                                                                         
    {                                                                           
        cout << "Введите три попарно неравных целых числа:\n";                 
        cin >> a >> b >> c;                                                     
    }                                                                           
    while(((a==b)||(b==c)||(a==c)) && (cout << "Введено неверно\n"));           
    cout << xyz(a,b,c);                                                         
}


Кстати, лучше не используйте cout << "Text\n", вместо этого cout << "Text" << endl

 Профиль  
                  
 
 Найти среднее
Сообщение13.01.2019, 13:36 
Аватара пользователя


10/10/18
762
At Home
Используется синтаксис C++
int mid( int a, int b, int c )
{
  switch( (a<b)*4 + (b<c)*2 + (a<c)*1 )
  {
  case 0: return b; // 000: a>b, b>c, a>c
  case 1: return 0; // 001: a>b, b>c, a<c: cannot be
  case 2: return c; // 010: a>b, b<c, a>c
  case 3: return a; // 011: a>b, b<c, a<c
  case 4: return a; // 100: a<b, b>c, a>c
  case 5: return c; // 101: a<b, b>c, a<c
  case 6: return 0; // 110: a<b, b<c, a>c: cannot be
  case 7: return b; // 111: a<b, b<c, a<c
  }
}
Такой switch компилятор оптимизирует в jmp.
То есть, условные переходы в функции — отсутствуют.
Всех — по паре, да ещё и симметрично относительно центральной горизонтали (между 3 и 4).

 Профиль  
                  
 
 Re: Найти среднее (С++)
Сообщение13.01.2019, 14:07 


06/04/18

323
Legioner93 в сообщении #1368224 писал(а):
Используется синтаксис C++
while(((a==b)||(b==c)||(a==c)) && (cout << "Введено неверно\n"));
Я понимаю, что (cout << "Введено неверно\n") — это тоже своего рода выражение. Но какое оно возвращает значение? Как повлияет на выполнение цикла?

 Профиль  
                  
 
 Re: Найти среднее (С++)
Сообщение13.01.2019, 14:18 
Аватара пользователя


14/12/17
1532
деревня Инет-Кельмында
Раз можно написать cout << "Введено неверно\n" << ...., то видимо cout << "Введено неверно\n" возвращает сам себя, cout.
Далее, operator bool() для cout (в условии будет вызываться именно он) - это скорее всего признак отсутствия ошибки, то есть программа может выйти из цикла, если первое условие все еще true, но cout почему-то сломался, не смог вывести приглашение и вернул false, и тогда xyz() выполнится для равных чисел. Не знаю, мне кажется лучше добавить , true к cout в условии:

while(((a==b)||(b==c)||(a==c)) && ((cout << "Введено неверно\n"), true));

 Профиль  
                  
 
 Re: Найти среднее
Сообщение14.01.2019, 15:31 
Экс-модератор
Аватара пользователя


23/12/05
12068
SergeCpp в сообщении #1368235 писал(а):
Используется синтаксис C++
int mid( int a, int b, int c )
{
  switch( (a<b)*4 + (b<c)*2 + (a<c)*1 )
  {
 ...
  }
}
Такой switch компилятор оптимизирует в jmp.
То есть, условные переходы в функции — отсутствуют.
Всех — по паре, да ещё и симметрично относительно центральной горизонтали (между 3 и 4).

1) Для бОльшей наглядности сложения можно заменить на |.
2) Статический анализатор может обругать такой код, сказав, что не все пути имеют return. Чтобы его удовлетворить, можно добавить поле default или воткнуть return за switch-ем.
3) Нулевое возвращаемое значение является вполне корректным для данной функции - не очень красиво писать его в return без какой-либо дополнительной обработки, даже если программа туда никогда не зайдет. Кстати, а зачем выписывать варианты, которые не могут случиться?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 24 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: Dmitriy40


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group