Самый большой и маленький из четырех целых чисел (без массивов, никаких функций, наименьших "если" )
Видите ли, я сам учу себя С++ (не совсем, я все еще откладываю -_-). Итак, теперь я начал университет, и они обучают C, и они заставили нас сделать программу ввода четырех целых чисел, и мы должны рассказать о самых больших и маленьких из них. Простой, нет?
Дело в том, что у меня уже есть хорошее понимание функций и массивов. Да, я МОГУ программировать это в массивах, без проблем. Но поскольку это была первая лаборатория, мы еще не "научились", поэтому я не могу использовать ни один из них, это было бы очень просто с этим.
Это то, что я там написал (он как-то чувствует себя не так).
#include<stdio.h>
int main(void)
{
int first, second, third, fourth;
printf("Enter four integers (separated by space): ");
scanf("%d %d %d %d", &first, &second, &third, &fourth);
if((first>second) && (first>third) && (first>fourth))
printf("\nFirst number is largest");
else if((second>first) && (second>third) && (second>fourth))
printf("\nSecond number is largest");
else if((third>second) && (third>first) && (third>fourth))
printf("\nThird number is largest");
else if((fourth>second) && (fourth>third) && (fourth>first))
printf("\nFourth number is largest");
if((first<second) && (first<third) && (first<fourth))
printf("\nFirst number is smallest");
else if((second<first) && (second<third) && (second<fourth))
printf("\nSecond number is smallest");
else if((third<second) && (third<first) && (third<fourth))
printf("\nThird number is smallest");
else if((fourth<second) && (fourth<third) && (fourth<first))
printf("\nFourth number is smallest");
printf("\n");
return 0;
}
Как вы можете видеть, он слишком длинный, скучный и сложный. Но, увидев, что все, что мы рассмотрели в классе на данный момент, это циклы и решения. Есть ли более элегантный способ сделать это? Тот, который использует меньше if
s? Не то, чтобы с этим что-то не так, но это может быть лучше.
P.S. Это не совсем "домашнее задание" или что-то еще. Я сделал программу, я просто хотел узнать, что я мог сделать, чтобы сделать ее лучше, и изучить лучшие методы программирования.
Ответы
Ответ 1
В соответствии с условием OP
Но, увидев, что все, что мы рассмотрели в классе, на данный момент, это циклы и решения. Есть ли более элегантный способ сделать это? Тот, который использует меньше if
s?
Только одна команда if
и один else if
и один цикл for
могут выполнить эту задачу. Простой и короткий!
#include <stdio.h>
int main()
{
int num, max, min;
printf ("Enter four numbers: ");
scanf ("%d", &num);
max = min = num;
for (int i = 0; i < 3; i++)
{
scanf ("%d", &num);
if (max < num)
max = num;
else if (min > num)
min = num;
}
printf ("The smallest and largest of given four numbers are %d and %d respectively.\n", min, max);
return 0;
}
Ответ 2
Попробуйте что-то вроде этого
int main(void) {
int a=-2,b=-3,c=-4,d=-5;
int max=a,min=a;
if(b>max){
max=b;
}else if(b<min){
min=b;
}
if(c>max){
max=c;
}else if(c<min){
min=c;
}
if(d>max){
max=d;
}else if(d<min){
min=d;
}
printf("max: %d min : %d",max,min);
return 0;
}
Демо
Ответ 3
Сделайте "ручной" сортировку слияния или, ну, только второй бит:
Концептуально сортировка слияния работает следующим образом
- Разделите несортированный список на n подписок, каждый из которых содержит 1 элемент (список из 1 элемента считается отсортированным).
- Неоднократно слияние подписок для создания новых подсписок до тех пор, пока не останется только 1 подсписок. Это будет отсортированный список.
![Merge sort merging step illustration]()
код:
int a = 5, b=4, c=7, d=9;
int min_ab, min_bc, min;
min_ab = a < b ? a : b;
min_bc = c < d ? b : c;
min = min_ab < min_bc ? min_ab : min_bc;
printf("%d", min);
.. и аналогично при max
Если вы предпочитаете, вы можете развернуть тернарный оператор на if (a < b) { min_ab = a; } else { min_ab = b; }
(разброс по нескольким строкам для удобства чтения).
Сортировка слияния имеет сложность O(n*log(n))
, поэтому вам больше не нужно O(n*log(n))
if
(см. статью статьи в википедии о сортировке слияния). Согласно Википедии, "... все это сортировочные сорта и поэтому не могут работать лучше, чем O (n log n) в среднем или худшем случае" (источник), поэтому я думаю, что это не должно быть слишком далеко с точки зрения минимального количества if
s. Хотя вы могли бы попытаться увидеть, приведет ли вручную выполнение одного из других алгоритмов к меньшему числу if
; -).
Ответ 4
Вся проблема в классе, которая требует поиска самого большого и самого маленького одновременно, - научить вас извлекать максимальную ценную информацию из каждого сравнения.
Например, если вы знаете, что a > b
истинно, из этого единственного сравнения вы должны понимать, что a
больше не является кандидатом для самого маленького и больше не должен участвовать в каких-либо сравнениях, посвященных поиску самых маленьких. И в то же время вы должны понимать, что b
больше не является кандидатом для самого большого. С 4 номерами два теста a > b
и c > d
уже четко разделяют числа на два независимых класса: два кандидата для самого большого и два кандидата для наименьшего. Остальное просто.
Другими словами, вся идея состоит в том, чтобы найти экстремальные значения параллельно, используя информацию, предоставленную каждым сравнением, для дальнейшей задачи поиска как самого маленького, так и самого большого значения.
if (first > second) {
int t = first; first = second; second = t;
}
if (third > fourth) {
int t = third; third = fourth; fourth = t;
}
/* Now 'first' and 'third' are candidates for the smallest,
while 'second' and 'fourth' are candidates for the largest */
int min = first < third ? first : third;
int max = second > fourth ? second : fourth;
Как вы можете видеть, для поиска обоих чисел требуется только четыре сравнения.
Обратите внимание, что приведенный выше код дает вам значения самого маленького и самого большого, но он не говорит вам об исходном "индексе" числа, которое предоставило каждое значение. Не сразу понятно, действительно ли это необходимо. Текст вашего вопроса ничего не говорит об этом, в то время как предоставленный вами образец кода реализует его. В любом случае нетрудно обновить приведенный выше код, чтобы он "отслеживал" происхождение чисел.
Ответ 5
Это слишком просто, учитывая, что числа - это a, b, c, d:
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
biggest = max (max(a,b), max(c,d))
smallest = min (min(a,b), min(c,d))
Здесь вы идете, нет утверждений, никаких функций (хотя последнее является самым глупым и вредным для адептов, о котором я когда-либо слышал).
Ответ 6
Вот решение с no if или elseif или функцией или макросом, но вместо этого используйте бит-сдвиг и вычитание; используя только один цикл для:
#include <stdio.h>
int main(){
int num , max, min;
printf("Enter four numbers: ");
scanf("%d", &num);
max = min = num;
for(int i = 0; i < 3; i++)
{
scanf("%d", &num);
max = max * (1 - ( (max-num) >> 31) )
+ num * ( (max-num) >> 31);
min = min * (1 - ( (num-min) >> 31) )
+ num * ( (num-min) >> 31);
}
printf("\n%d %d", max, min);
return 0;
}
Операция (max-num) >> 31)
фиксирует знак разницы, который при умножении на второе число дает минимальное значение сравнения.
Это происходит из старого кода SQL с тех пор, как на этом языке была построена конструкция CASE WHEN.
Ответ 7
Одной из идей может быть вычисление максимума и минимума первых двух чисел. Затем вы сравниваете остальные числа в парах. Большая одна из каждой пары сравнивается с максимальным током, а меньшая из каждой пары сравнивается с текущим минимумом. Таким образом, вы выполняете 3 сравнения для каждых 2 элементов, что немного более эффективно, чем ответ Arpit (2 сравнения для каждого элемента).
В коде:
#include <stdio.h>
int main(int argc, char **argv) {
int a, b, c, d;
printf("Enter four integers (separated by space): ");
scanf("%d %d %d %d", &a, &b, &c, &d);
int max, min;
if (a > b) {
max = a;
min = b;
}
else {
max = b;
min = a;
}
if (c > d) {
if (c > max) {
max = c;
}
if (d < min) {
min = d;
}
}
else {
if (d > max) {
max = d;
}
if (c < min) {
min = c;
}
}
printf("max = %d, min = %d\n", max, min);
return 0;
}
Ответ 8
Это код C имеет только 4 оператора if. Он перемещает максимальное число в позицию d и минимальное число в позицию. Значения b и c неправильно упорядочены в последовательности, но поскольку требования требуют минимального и максимального значения, этот код завершает задание:
#include <stdio.h>
int main() {
int a, b, c, d, temp;
printf("Enter four digits: ");
scanf("%d %d %d %d", &a, &b, &c, &d);
if ( a > b){
temp = a; a = b ; b = temp;
}
if ( c > d){
temp = c; c = d ; d = temp;
}
if ( b > d ){
temp = b; b = d; d = temp;
}
if ( a > c){
temp = a; a = c ; c = temp;
}
printf("Max %d\nMin %d\n", d, a);
return 0;
}
Ответ 9
Please have at the following
private int GetLargerValue(int num1, int num2, int num3, int num4)
{
int largeValue = 0;
if (num1 > num2)
{
if (num1 > num3)
largeValue = (num1 > num4) ? num1 : num4;
else
largeValue = (num3 > num4) ? num3 : num4;
}
else if (num2 > num3)
largeValue = (num2 > num4) ? num2 : num4;
else
largeValue = (num3 > num4) ? num3 : num4;
return largeValue;
}
Ответ 10
int max_of_four(int a, int b, int c, int d){
int res=a;
if(b/res)
res=b;
if(c/res)
res=c;
if(d/res)
res=d;
return res;
}
int main() {
int a, b, c, d;
scanf("%d %d %d %d", &a, &b, &c, &d);
int ans = max_of_four(a, b, c, d);
printf("%d", ans);
return 0;
}
Ответ 11
Для абсолютной производительности, т.е. Минимальные сравнения и задания.
Комментарии на каждом уровне показывают значения для кандидата min и max. Идея состоит в том, чтобы уменьшить наборы на каждом уровне, пока для каждого набора не будет только одного элемента. Это можно сделать только с 4 сравнениями и двумя присваиваниями.
// min = a b c d
// max = a b c d
if (a <= b)
{
// min = a c d
// max = b c d
if ( c <= d){
// min = a c
// max = b d
min = a <= c ? a : c;
max = b > d ? b : d;
}else{
// min = a d
// max = b c
min = a <= d ? a : d;
max = b > c ? b : c;
}
}
else
{
// min = b c d
// max = a c d
if ( c <= d){
// min = b c
// max = a d
min = b < c ? b : c;
max = a > d ? a : d;
}else{
// min = b d
// max = a c
min = b < d ? b : d;
max = a > c ? a : c;
}
}
Ответ 12
Я видел этот ответ, который использовался для утверждения цикла и if else, однако я опубликую решение, которое, как я полагаю, будет работать быстрее и будет использовать только четыре переменные. Итак, вот оно...
#include<stdio.h>
void main()
{
int a,b,c,d;
printf("Enter four numbers of your choice");
scanf("%d%d%d%d",&a,&b,&c,&d);
a>b&&a>c?a>d?printf("%d",a):printf("%d" ,d):(b>c&&b>d)?printf("%d",b):c>d?printf("%d", c):printf("%d",d);
}