Глобальные массивы: функция SearchItem()
Поскольку мы используем глобальные массивы для хранения данных, то вполне вероятно, что нам понадобятся функции поиска элемента в массиве.
Технология поиска будет зависеть от того, упорядочен ли наш массив:
- Если массив неупорядоченный, то самым очевидным методом найти какой-нибудь элемент будет простой перебор всех элементов массива.
- Если массив упорядоченный, то наилучшим решением (наиболее оптимальным по скорости поиска) будет двоичный поиск.
Итак, напишем функцию SearchItem(), которая осуществляет поиск в массиве и возвращает:
- индекс найденного элемента в массиве, если элемент найден; или
- 0 - если элемента в массиве нет; или
- -1 - если произошла какая-то ошибка.
//+--------------------------------------------------------------------------------------------------------+ //| Функция SearchItem() | //| | //| Ищет элемент в массиве. Возвращает индекс элемента или 0, если | //| элемент был не найден, и -1 - в случае ошибки | //| | //| Параметры: | //| array - имя массива | //| item - новый элемент массива | //| is_sorted - флаг отсортированности массива (может быть изменен | //| в процессе выполнения функции, если возникнут | //| ошибки при сортировке) | //+--------------------------------------------------------------------------------------------------------+ int SearchItem(string array, double item, bool &is_sorted) { // Залокировать критическую секцию string critical_section = array+"Lock"; if (Lock(critical_section)!=0) return(-1);
// Количество элементов массива хранится в переменной с именем, // равным имя массива + "Count" string gv_count; gv_count = array+"Count";
int count, err;
// Если глобальная переменная не существует, то элементов нет if (!GlobalVariableCheck(gv_count)) { err = GetLastError(); if (err!=0) { // Разлокировать критическую секцию Unlock(critical_section);
// Вывести сообщение об ошибке и выйти Print("SearchItem()->GlobalVariableCheck(): ошибка ", err); return(-1); } else count = 0; } else // переменная существует, получим количество элементов count = GlobalVariableGet(gv_count);
// если массив пустой - вернуть 0 if (count==0) { // Разлокировать критическую секцию Unlock(critical_section);
return(0); }
// если массив неотсортированный, то найдем элемент перебором if (!is_sorted) { int i; for (i=1; i<=count; i++) if (item==GlobalVariableGet(array+DoubleToStr(i, 0))) { // Разлокировать критическую секцию Unlock(critical_section);
return(i); } } else { // массив отсортированный, поэтому произведен двоичный поиск int pos1, pos2, mid; pos1 = 1; pos2 = count;
while (pos1+1<pos2) { mid = (pos1+pos2)/2;
if (item>GlobalVariableGet(array+DoubleToStr(mid, 0))) pos1 = mid; else pos2 = mid; }
if (GlobalVariableGet(array+DoubleToStr(pos1, 0))==item) { // Разлокировать критическую секцию Unlock(critical_section);
return(pos1); } if (GlobalVariableGet(array+DoubleToStr(pos2, 0))==item) { // Разлокировать критическую секцию Unlock(critical_section);
return(pos2); } }
// Разлокировать критическую секцию Unlock(critical_section);
return(0); }
В следующем выпуске я подробно разберу исходный код этой функции, а также немного раскажу о принципах двоичного поиска.
Все статьи по теме "Пишем советников для MetaTrader 4".
- Механическая торговая система - миф или реальность?
- С чего начать при написании советника:
- Создаем нового советника - Настраиваем параметры. - Язык MetaQuotes Language 4: