« Предыдущий пост | На главную страницу | Следующий пост »

Глобальные массивы: технология поиска

В прошлом выпуске я привел код функции SearchItem(), с помощью которой можно найти элемент в массиве.

Эта функция возвращает:

  • индекс найденного элемента в массиве, если элемент найден; или
  • 0 - если элемента в массиве нет; или
  • -1 - если произошла какая-то ошибка.

Для того, чтобы понять принцип работы этой функции, будет полезно рассказать о различных технологиях поиска.

Прежде всего код функции SearchItem() начинается с того, что мы локируем критическую секцию, чтобы обеспечить монопольный доступ к данным массива:

   // Залокировать критическую секцию
   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);

После этого мы смотрим, отсортирован ли массив:

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

Технология поиска простым перебором:

      int i;
      for (i=1; i<=count; i++)
        if (item==GlobalVariableGet(array+DoubleToStr(i, 0)))
         {
          // Разлокировать критическую секцию
          Unlock(critical_section);

return(i);
}

Технология двоичного поиска:

  1. Левая граница поиска - первый элемент, правая граница поиска - последний эелемент.
  2. Берем элемент, который находится посередине между левой и правой границами.
  3. Если этот элемент меньше того, который мы ищем, то сдвигаем левую границу поиска к середине нашего диапазона (т.к. однозначно, что искомый элемент находится выше серединного). В противном случае - сдвигаем правую границу поиска к середине диапазона. Каждый раз диапазон поиска уменьшается в два раза.
  4. Повторяем шаги 2 и 3, пока диапазон больше 2 элементов

Такая технология поиска гарантирует быстрое нахождение элемента в отсортированном массиве. Например, в массиве из 1,000 элементов мы найдем элемент за 10 итераций, а в массиве из 1,000,000,000 элементов - за 30 итераций. В то время как поиск путем простого перебора даст тот же результат в среднем за 500 и 500,000,000 итераций соответственно. Выигрыш в скорости очень ощутим.

Напомню кусок кода, который осуществляет двоичный поиск в отсортированном массиве:

      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);
        } 
     }    

В следующем выпуске я расскажу о том, как с помощьюе функции GetItem() получить значение элемента в определенной позиции массиве.



Все статьи по теме "Пишем советников для MetaTrader 4".

« Предыдущий пост | На главную страницу | Следующий пост »

Подписаться на мою рассылку



Размещение статьи "Глобальные массивы: технология поиска" на Вашем сайте

Размещение статьи "Глобальные массивы: технология поиска" на Вашем сайте возможно при условии выполнениия следующих условий:

  • Запрещается изменение оригинального текста без согласия автора - Андрея Ведихина.
  • Должен быть указан первоисточник. В случае публикации в интернете Вы должны разместить следующий код гиперссылки без изменений:
  • Запрещается коммерческое использование материалов, взятых с блога "Интернет-трейдинг на форекс / forex". Доступ к ним должен быть свободным, без взимания какой-либо платы, без обязательной регистрации и/или заполнения опросного листа (анкеты) и т.д.

В случае выполнения данных условий не требуется согласия автора блога "Интернет-трейдинг на форекс / forex" на размещение статьи "Глобальные массивы: технология поиска" на Вашем сайте.

Журнал FOREX MAGAZINE:



Архив номеров FOREX MAGAZINE
Котировки Forex:

Счетчики:

Авторские права © 2005-2006 Андрей Ведихин

Условия использования материалов блога "Интернет-трейдинг на форекс / forex"

Контакты с автором:


Движок сайта:
Movable Type 5.04