Глобальные массивы: функция 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: