Как найти максимум между двумя числами

Firstly, declare and initialize two numbers.

int num1 = 50;
int num2 = 90;

With that, use if-else to find the maximum number.

if (num1 > num2) {
   maxNum = num1;
} else {
   maxNum = num2;
}

Above, we have set the maximum value to the variable maxNum and printed it later on.

The following is the complete example to find maximum between 2 numbers in C#.

Example

 Live Demo

using System;
namespace Demo {
   class Program {
      static void Main(string[] args) {
         int num1 = 50;
         int num2 = 90;
         int maxNum;
         Console.WriteLine("Number 1: "+num1);
         Console.WriteLine("Number 2: "+num2);
         if (num1 > num2) {
            maxNum = num1;
         } else {
            maxNum = num2;
         }
         Console.WriteLine("Maximum number is: "+maxNum);
         Console.ReadKey() ;
      }
   }
}

Output

Number 1: 50
Number 2: 90
Maximum number is: 90

Самый распространенный вариант реализации функции max — проверка знака выражения a - b. В этом случае мы не можем использовать оператор сравнения, но можем использовать умножение.

Примечание Смысл задачи не в том, чтобы скрыть сравнение или условие в какую-нибудь стандартную функцию типа abs() или стандартный оператор типа целочисленного деления, а в том, чтобы всё это сделать вообще без инструкций ветвления на уровне процессора.

Обозначим знак выражения a - b как k. Если a - b >= 0, то k = 1, иначе k = 0. Пусть q будет инвертированным значением k.

Код будет иметь вид:

/* Отражаем 1 в 0 и 0 в 1 */
int flip(int bit) {
	return 1^bit;
}

/* Возвращаем 1, если число положительное, и 0, если отрицательное*/
int sign(int a) {
	return flip((a >> (sizeof(int) * CHAR_BIT - 1)))) & 0x1);
}

int getMaxNaive(int a, int b) {
	int k = sign(a - b);
	int q = flip(k);
	return a * k + b * q;
}

Это почти работоспособный код (можете проверить). Проблемы начинаются при переполнении. Предположим, что a = INT_MAX - 2 и b = -15. В этом случае a - b перестанет помещаться в INT_MAX и вызовет переполнение (значение станет отрицательным).

Можно использовать тот же подход, но придумать другую реализацию. Нам нужно, чтобы выполнялось условие k = 1, когда a > b. Для этого придется использовать более сложную логику.

Когда возникает переполнение a - b? Только тогда, когда a положительное число, а b отрицательное (или наоборот). Трудно обнаружить факт переполнения, но мы в состоянии понять, что a и b имеют разные знаки. Если у а и b разные знаки, то пусть k = sign(a).

Логика будет следующей:

1. если у a и b разные знаки:
// если a > 0, то b < 0 и k = 1.
// если a < 0, то b > 0 и k = 0.
// так или иначе, k = sign(a)
2. пусть k = sign(a)
3. иначе пусть k = sign(a - b) // переполнение невозможно

Приведенный далее код реализует этот алгоритм, используя умножение вместо операторов сравнения (проверить):

int getMax(int a, int b) {
	int c = a - b;
	
	int sa = sign(a); // если a >= 0, то 1, иначе 0
	int sb = sign(b); // если a >= 1, то 1, иначе 0
	int sc = sign(c); // зависит от переполнения a - b
	
	/* Цель: найти k, которое = 1, если а > b, и 0, если a < b.
	 * если a = b, k не имеет значения */

	// Если у а и b равные знаки, то k = sign(a)
	int use_sign_of_a = sa ^ sb;
	
	// Если у a и b одинаковый знак, то k = sign(a - b)
	int use_sign_of_c = flip(sa ^ sb);
	
	int k = use_sign_of_a * sa + use_sign_of_c * sc;
	int q = flip(k); // отражение k

	return a * k + b * q;
}

Отметим, что для большей наглядности мы разделяем код на методы и вводим переменные. Это не самый компактный или эффективный способ написания кода, но так мы делаем код понятнее.

Разбор взят из книги Гейл Л. Макдауэлл «Cracking the Coding Interview» (есть в переводе).

Алгоритмы определения минимума и максимума. Пример


Содержание

  • 1. Алгоритм min. Поиск минимума между двумя значениями
  • 2. Алгоритм min_element. Поиск минимального элемента в наборе значений
  • 3. Алгоритм max. Поиск максимума между двумя значениями
  • 4. Алгоритм max_element. Поиск максимума в последовательности
  • 5. Алгоритм lexicographical_compare. Сравнить поэлементно 2 последовательности
  • Связанные темы

1. Алгоритм min. Поиск минимума между двумя значениями

Алгоритм min сравнивает два объекта и возвращает меньший из них. Критерий сравнения элементов может быть задан предикатом.
Алгоритм имеет несколько перегруженных реализаций

template <class Type>
  constexpr const Type& min(
  const Type& left,
  const Type& right);

template <class Type, class Pr>
  constexpr const Type& min(
  const Type& left,
  const Type& right,
  BinaryPredicate pred);

template <class Type>
  constexpr Type min(
  initializer_list<Type> ilist);

template <class Type, class Pr>
  constexpr Type min(
  initializer_list<Type> ilist,
  BinaryPredicate pred);

где

  • left, right – сравниваемые объекты;
  • pred – предикат, используемый для сравнения двух объектов. Это может быть также лямбда-выражение;
  • inlist – объект, содержащий элементы для сравнения.

Пример.

#include <iostream>
#include <list>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;

// Функция сравнения.
// Если знак < заменить на >, то будет поиск максимума.
bool MoreThan(int a, int b)
{
  return a < b;
}

void main()
{
  // Алгоритм min – поиск минимума между двумя значениями
  // 1. Поиск между значениями типа double
  double minDouble = min(2.8, 3.6);
  cout << "minDouble = " << minDouble << endl;

  // 2. Поиск между целыми числами,
  // используется функция сравнения
  int minInt = min(29, 36, MoreThan);
  cout << "minInt = " << minInt << endl;
}

Результат

minDouble = 2.8
minInt = 29

 

2. Алгоритм min_element. Поиск минимального элемента в наборе значений

Алгоритм выполняет поиск малейшего элемента в заданном диапазоне. Критерий упорядочения может быть задан бинарным предикатом.

Наиболее употребляемые перегруженные реализации алгоритма

template <class ForwardIterator>
constexpr ForwardIterator min_element(
  ForwardIterator first,
  ForwardIterator last );

template <class ForwardIterator, class Compare>
constexpr ForwardIterator min_element(
  ForwardIterator first,
  ForwardIterator last,
  Compare pred);

где

  • first, last – прямые итераторы, указывающие соответственно на первый и последний элемент диапазона;
  • pred – бинарный предикат, который задает условие, когда один элемент меньше другого. Если первый элемент меньше другого, то предикат должен возвращать true.

Пример.

#include <iostream>
#include <list>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;

// Функция сравнения.
// Если знак < заменить >, то будет поиск максимума.
bool MoreThan(int a, int b)
{
  return a < b;
}

void main()
{
  // Алгоритм min_element - поиск минимума в наборе значений
  // 1. Поиск в векторе чисел типа double
  vector<double> V = { 2.8, 1.6, 2.9, 3.3, 4.5, -1.8, -2.2 };
  vector<double>::iterator itV = min_element(V.begin(), V.end());
  cout << "min_element(V) = " << *itV << endl;

  // 2. Поиск между целыми числами,
  // используется функция сравнения
  list<int> L = { 2, 3, 8, -4, 1, 3, -2 };
  list<int>::iterator itL = min_element(L.begin(), L.end(), MoreThan);
  cout << "min_element(L) = " << *itL << endl;

  // 3. Поиск между целыми числами,
  // используется лямбда-выражение
  itL = min_element(L.begin(), L.end(), [](int a, int b) { return a < b; });
  cout << "min_element(L) = " << *itL << endl;
}

Результат

min_element(V) = -2.2
min_element(L) = -4
min_element(L) = -4

 

3. Алгоритм max. Поиск максимума между двумя значениями

Алгоритм max сравнивает два объекта и возвращает больший из них. В алгоритме разрешается задавать критерий упорядочения с помощью бинарного предиката.

Перегруженные реализации алгоритма следующие

template <class Type>
constexpr Type& max(
  const Type& left,
  const Type& right);

template <class Type, class Pr>
  constexpr Type& max(
  const Type& left,
  const Type& right,
  BinaryPredicate pred);

template <class Type>
constexpr Type& max (
  initializer_list<Type> ilist);

template <class Type, class Pr>
constexpr Type& max(
  initializer_list<Type> ilist,
  BinaryPredicate pred);

где

  • left, right – соответственно первый и второй из сравниваемых объектов;
  • pred – бинарный предикат, задающий способ сравнения объектов;
  • ilist – список с объектами, которые нужно сравнить.

Пример.

#include <iostream>
#include <list>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;

// Функция сравнения.
// Если знак < заменить >, то будет поиск минимума.
bool LessThan(int a, int b)
{
  return a < b;
}

void main()
{
  // Алгоритм max – поиск максимума между двумя значениями
  // 1. Поиск между значениями типа double
  double maxDouble = max(2.8, 3.6);
  cout << "maxDouble = " << maxDouble << endl;

  // 2. Поиск между целыми числами, используется функция сравнения
  int maxInt = max(29, 36, LessThan);
  cout << "maxInt = " << maxInt << endl;
}

Результат

maxDouble = 3.6
maxInt = 36

 

4. Алгоритм max_element. Поиск максимума в последовательности

Алгоритм max_element возвращает первое вхождение наибольшего элемента в последовательности, задаваемой диапазоном. В алгоритме можно указать бинарный предикат, задающий условие поиска максимального значения.

Алгоритм имеет несколько перегруженных реализаций, наиболее распространённые из которых следующие

template <class ForwardIterator>
constexpr ForwardIterator max_element(
  ForwardIterator first,
  ForwardIterator last );

template <class ForwardIterator, class Compare>
constexpr ForwardIterator max_element(
  ForwardIterator first,
  ForwardIterator last,
  Compare pred );

здесь

  • first, last – прямые итераторы, которые указывают соответственно на первый и последний элемент рассматриваемого диапазона;
  • pred – бинарный предикат, который задает условие, когда один элемент меньше другого. Если первый элемент меньше второго, то предикат должен возвращать true.

Пример.

#include <iostream>
#include <list>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;

// Функция сравнения.
// Если знак < заменить >, то будет поиск минимума.
bool MoreThan(int a, int b)
{
  return a < b;
}

void main()
{
  // Алгоритм max_element - поиск максимума в наборе значений.
  // 1. Поиск в векторе чисел типа double
  vector<double> V = { 2.8, 1.6, 2.9, 3.3, 4.5, -1.8, -2.2 };
  vector<double>::iterator itV = max_element(V.begin(), V.end());
  cout << "max_element(V) = " << *itV << endl;

  // 2. Поиск между целыми числами,
  // используется функция сравнения
  list<int> L = { 2, 3, 8, -4, 1, 3, -2 };
  list<int>::iterator itL = max_element(L.begin(), L.end(), MoreThan);
  cout << "max_element(L) = " << *itL << endl;

  // 3. Поиск между целыми числами,
  // используется лямбда-выражение
  itL = max_element(L.begin(), L.end(), [](int a, int b) { return a < b; });
  cout << "min_element(L) = " << *itL << endl;
}

Результат

max_element(V) = 4.5
max_element(L) = 8
min_element(L) = 8

 

5. Алгоритм lexicographical_compare. Сравнить поэлементно 2 последовательности

Алгоритм выполняет поэлементное сравнение двух последовательностей, чтобы определить какой элемент из двух последовательностей меньше.

Распространенные реализации алгоритма следующие

template <class InputIterator1, class InputIterator2>
bool lexicographical_compare(
  InputIterator1 first1,
  InputIterator1 last1,
  InputIterator2 first2,
  InputIterator2 last2 );

template <class InputIterator1, class InputIterator2, class Compare>
bool lexicographical_compare(
  InputIterator1 first1,
  InputIterator1 last1,
  InputIterator2 first2,
  InputIterator2 last2,
  Compare pred );

где

  • first1, last1 – итераторы, задающие диапазон элементов первой последовательности;
  • first2, last2 – итераторы, задающие пределы второй последовательности.

Поэлементное сравнение последовательностей происходит по следующим правилам:

  • находятся первые 2 неравных соответствующих элемента и результат их сравнения является результатом сравнения двух последовательностей;
  • если элементы последовательностей равны, то сравниваются длины последовательностей. Больше считается та последовательность, количество элементов в которой больше;
  • если последовательности идентичны и имеют одинаковое количество элементов, то результатом сравнения является false.

Пример.

#include <iostream>
#include <queue>
#include <vector>
#include <list>
#include <functional>
#include <algorithm>
using namespace std;

int main()
{
  // Алгоритм lexicographical_compare - сравнивает 2 последовательности поэлементно,
  // если последовательности идентичны - результат false.

  // 1. Объявить два вектора
  vector<double> V1 = { 1.1, 2.2, 2.7, 2.8, 3.2, 5.5 };
  vector<double> V2 = { 1.1, 2.2, 2.7, 2.8, 3.2, 5.5 };

  // 2. Вызвать алгоритм, получить результат
  bool res = lexicographical_compare(V1.begin(), V1.end(), V2.begin(), V2.end());

  // 3. Обработать результат
  if (res)
    cout << "true => V1 != V2" << endl;
  else
    cout << "false => V1 == V2" << endl;
}

Результат

false => V1 == V2

 


Связанные темы

  • Алгоритмы перестановок. Алгоритмы next_permutation, prev_permutation
  • Немодифицирующие алгоритмы. Поиск. Алгоритмы find, find_if, find_first_of, find_end, adjanced_find, search, search_n
  • Немодифицирующие алгоритмы. Алгоритмы count, count_if, equal, equal_range, mismatch
  • Алгоритмы для работы с множествами. Алгоритмы includes, set_union, set_intersection, set_difference, set_symmetric_difference
  • Модифицирующие алгоритмы. Часть 1. Алгоритмы изменяющие значения элементов последовательности. Алгоритмы for_each, transform, fill, fill_n, generate, generate_n
  • Модифицирующие алгоритмы. Часть 2. Алгоритмы обмена значениями элементов последовательности. Алгоритмы swap, swap_ranges, iter_swap

 


Лучший ответ

Андрей

Высший разум

(267296)


3 года назад

максимальное: (a + b + abs(a – b)) / 2
минимальное: (a + b – abs(a – b)) / 2

Остальные ответы

Ника Fair

Мастер

(1068)


3 года назад

Как ты собрался это сделать?

Lenar

Гуру

(3127)


3 года назад

тернарный оператор

Валерий Кондратенко

Мастер

(1054)


3 года назад

Ты сам то понял что написал? “Как сравнивать (иначе как узнать какое больше) числа без сравнения?”

Сергей Бизон

Искусственный Интеллект

(459299)


3 года назад

Да элементарно!
Выражение (x%y) / x будет равно 1 при x<= y и 0 при x > y

Андрей ****

Профи

(603)


3 года назад

отсортируй два числа стандартной сортировкой=0

Александр Береза

Ученик

(247)


2 года назад

((a // b) * a + (b // a) * b) // (a // b + b // a). Согласен, нетривиально, но работает

Poza4ka

Знаток

(306)


7 месяцев назад

x=[1,2,3]
print (max(x))

Я пытаюсь запустить с этим блоком кода, но он не работает

Switch (num1>num2) {
case 0:
  document.write(num2);
  break;
case 1:
  document.write(num1);
 break;
}

2018-08-11 02:25

4
ответа

Вы можете использовать что-то простое, как Math.max(5, 10);

const numOne = 5;
const numTwo = 10;

console.log(`Bigger number is: ${Math.max(numOne, numTwo)}`);

Или если вы абсолютно “должны” использовать switch statement, вы можете попробовать что-то вроде этого:

const numOne = 5;
const numTwo = 10;

switch(true) {
    case (numOne > numTwo):
        console.log(`Bigger number is ${numOne}`);
        break;
    case (numOne < numTwo):
        console.log(`Bigger number is ${numTwo}`);
        break;
    case (numOne === numTwo):
        console.log(`${numOne} is equal to ${numTwo}`);
        break;
     default: console.log(false, '-> Something went wrong');
}

2018-08-11 02:43

Логические операции возвращают логическое значение в Javascript.

document.write записывает выражения HTML или код JavaScript в документ, console.log печатает результат на консоли браузера.

   switch (num1>num2) {
      case true:
          console.log(num1);
       break;
       case false:
           console.log(num2);
       break;
    }

2018-08-11 02:32

switch (с нижним регистром s) использует строгое сравнение === поэтому значение логического типа 11 > 10 никогда ===0 или же 1,

Вам нужно проверить логическое значение, если вы хотите сделать это следующим образом:

let num1 = 10
let num2 = 20

switch (num1>num2) {
    case false:
      console.log(num2);
      break;
    case true:
      console.log(num1);
     break;
    }
    
    

Если по какой-то причине вам дали числа, вы можете явно привести их к логическим значениям с чем-то вроде case !!0: но это начинает становиться немного жестким для глаз.

Если ваша цель – найти максимум двух чисел, Math.max(num1, num2) трудно бить за читабельность.

2018-08-11 02:33

Вы бы просто использовали больше, чем / меньше, чем внутри оператора switch.

var x = 10;
var y = 20;

switch(true) {
    case (x > y):
        console.log(x);
        break;
    case ( y > x):
        console.log(y);
        break;
}

2018-08-11 02:31

Добавить комментарий