Нахождение индекса минимального значения в массиве, ИСПОЛЬЗУЯ min (a, b) - PullRequest
0 голосов
/ 22 января 2020

Задача найти индекс минимального значения в массиве, просто зацикливаясь, сохраняя индекс наименьшего значения и обновляя его с помощью

min_index = arr[i] < arr[min_index] ? i : min_index;

, очень проста.

Однако нам дали ту же задачу, однако нам было указано, что мы ДОЛЖНЫ использовать функцию min (a, b).

Это может работать:

min_index = min(arr[i], arr[min_index]) == arr[i] ? i : min_index;

Однако, числа, с которыми мы имели дело, были числами с неизвестной точностью.

Ответы [ 3 ]

1 голос
/ 22 января 2020

Я не думаю, что с вашим решением для массива элементов с плавающей запятой что-то не так (я предполагаю, что нет NaN). std::min возвращает ссылку на свой аргумент с более низким значением (которое определено для номеров FP, не относящихся к Nan). Таким образом, std::min(arr[i], arr[min_index]):

  1. либо возвращает ссылку на arr[i], если она меньше или равна arr[min_index],
  2. , либо возвращает ссылку на arr[min_index], если это больше, чем arr[i].

В 1., когда вы сравниваете результат std::min с arr[i], вы сравниваете два очень одинаковых объекта FP, которые гарантированно будут оценены ot true.

В 2. вы сравниваете два объекта FP с разными значениями, которые гарантированно оцениваются как false.

Поэтому, я думаю, ваше решение работает хорошо ,

Имейте в виду, что ошибки округления за пределами вашего решения могут , казалось бы, сломать его. Рассмотрим следующий пример:

float arr[3] = { 1.0f / 3.0f, 0.33333334, 2.0f };
size_t min_index = 0;
for (size_t i = 1; i < 3; i++)
   min_index = std::min(arr[i], arr[min_index]) == arr[i] ? i : min_index;
std::cout << min_index;

1/3 - наименьшее число, но это напечатало 1 в моего эксперимента , поскольку ваш код сравнивается компьютерное представление из 1.0f/3.0f с компьютерное представление из 0.33333334, которые оба являются объектами округления. Следовательно, числа, фактически сохраненные в arr, отличаются.

0 голосов
/ 22 января 2020
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int n;
    cin>>n;
    float arr[n];
    float min_index = 0;
    float mini = 0;


    for(int i=0; i<n; i++)
    {
        cin>>arr[i];
    }

    mini = arr[0];

    for(int i=0; i<n; i++)
    {
        mini = min(arr[i], mini);
    }

    for(int i=0; i<n; i++)
    {
        if(arr[i] == mini)
            min_index = i;
    }

    cout<<min_index<<endl;

    return 0;
}

отлично работает с поплавком! Вы могли бы быть более точным c о вашей точности?

0 голосов
/ 22 января 2020

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

min_index = abs(min(arr[i], arr[min_index]) - arr[i]) > error ? i : min_index;

Где error - это число ошибок, которое вы хотите разрешить, а abs() равно std::abs().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...