Программирование >>  Инициализация объектов класса, структура 

1 ... 61 62 63 [ 64 ] 65 66 67 ... 395


if ( minVal <= ivec[ i ] ) { if ( minVal == ivec[ i ] ) ++occurs;

else {

minVal = ivec[ i ]; occurs = 1;

В некоторых стилях программирования рекомендуется всегда употреблять фигурные скобки при использовании инструкций if-else, чтобы не допустить возможности неправильной интерпретации кода.

Вот первый вариант функции min() . Второй аргумент функции будет возвращать количество вхождений минимального значения в вектор. Для перебора элементов массива используется цикл for. Но мы допустили ошибку в логике программы. Сможете

#include <vector>

int min( const vector<int> &ivec, int &occurs )

int minVal = 0; occurs = 0;

int size = ivec.size();

size

for ( int ix = 0; ix < size; ++ix ) { if ( minVal == ivec[ ix ]

++occurs;

else

if ( minVal > ivec[ ix ] ) { minVal = ivec[ ix ]; occurs = 1;

return minVal;

ли вы заметить ее?

Обычно функция возвращает только одно значение. Однако согласно нашей спецификации в точке вызова должно быть известно не только само минимальное значение, но и количество его вхождений в вектор. Для возврата второго значения мы использовали параметр тина ссылка. (Параметры-ссылки рассматриваются в разделе 7.3.) Любое присваивание значения ссылке occurs изменяет значение неременной, на которую она ссылается:



int main()

int occur cnt = 0; vector< int > ivec

occur cnt получает значение occurs из функции min()

int minval = min( ivec, occur cnt );

...

Альтернативой использованию параметра-ссылки является применение объекта класса pair, представленного в разделе 3.14. Функция min() могла бы возвращать два значения

альтернативная реализация с помощью пары

#include <uti1ity> #include <vector>

typedef pair<int,int> min va1 pair; min va1 pair

min( const vector<int> sivec ) {

int minVal = 0; int occurs = 0;

то же самое ..

return make pair( minVal, occurs ); в одной паре:

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

Программу можно изменить, инициализировав minVal первым элементом вектора:

int minVal = ivec[0];

Теперь функция работает правильно. Однако в ней выполняются некоторые лишние действия, снижающие ее эффективность.



исправленная версия min()

оставляющая возможность для оптимизации ...

int minVal = ivec[0]; occurs = 0;

int size = ivec.size();

for ( int ix = 0; ix < size; ++ix )

if ( minVal == ivec[ ix ] ) ++occurs;

...

Поскольку ix инициализируется нулем, на первой итерации цикла значение первого элемента сравнивается с самим собой. Mожно инициализировать ix единицей и избежать ненужного выполнения первой итерации. Однако при оптимизации кода мы допустили другую ошибку (наверное, стоило все оставить как было!). Сможете ли вы ее

оптимизированная версия min(), к сожалению, содержащая ошибку...

int minVal = ivec[0]; occurs = 0;

int size = ivec.size();

for ( int ix = 1; ix < size; ++ix )

if ( minVal == ivec[ ix ] ) ++occurs;

обнаружить?

...

Если ivec[0] окажется минимальным элементом, переменная occurs не получит

int minVal = ivec[0];

значения 1. Конечно, исправить это очень просто, но сначала надо найти ошибку:

occurs = 1;

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

Вот окончательная версия функции min() и программа main() , проверяющая ее работу:



1 ... 61 62 63 [ 64 ] 65 66 67 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика