Очистка массива от заданного (ых) элементов - страница 12

 
Alexey Viktorov:

Так вот если ордер закрылся, то его надо из массива "вычеркнуть". В таких случаях я пользовался копированием массива "сам в себя" и сокращением размерности на единицу. 

я в таком случае несуществующий тикет записывал в массив -1 , и ждал когда все ордера будут закрыты и удалял весь массив (размер размер массива устанавливаю =1).

При таком подходе элемент массива тикетов (если не существует ордер) всего с одним условием проверяется: if(ArrayOfTicket[i] > 0) .....

 имхо так быстрее чем постоянно массив "перетряхивать"

 
Igor Makanu:

я в таком случае несуществующий тикет записывал в массив -1 , и ждал когда все ордера будут закрыты и удалял весь массив (размер размер массива устанавливаю =1).

При таком подходе элемент массива тикетов (если не существует ордер) всего с одним условием проверяется: if(ArrayOfTicket[i] > 0) .....

 имхо так быстрее чем постоянно массив "перетряхивать"

Ничего не понял... А какая разница, удалять поэлементно или проверять индексы несуществующих ордеров...массив по любому перетрахивается...

В общем, как сегодня в новостях сказали, запатентовать вкус невозможно. Фломастеры только на цвет разные, а на вкус все одинаковые.

 
Alexey Viktorov:

Ничего не понял... А какая разница, удалять поэлементно или проверять индексы несуществующих ордеров...массив по любому перетрахивается...

В общем, как сегодня в новостях сказали, запатентовать вкус невозможно. Фломастеры только на цвет разные, а на вкус все одинаковые.

удаление элемента подразумевает копирование оставшихся элементов массива, я не удаляю элементы массива, а маркирую значением -1 несуществующие элементы (тикеты), и удаляю массив тикетов когда нет рыночных ордеров

насчет фломастеров, однозначно так и есть, зависит от задачи, в принципе при оптимизации обычно 2 решения:

- или добавляем сложность алгоритма, но экономим память и тратим вычислительные ресурсы ПК 

- или упрощаем алгоритм и экономим вычислительные ресурсы, но потребляем память

 

Контрольная сумма считается не верно, если в массиве есть 0 то может быть ошибка

Вариант Никитина как раз на такой ошибке работает. 

Файлы:
456.mq5  20 kb
 
Vladimir Pastushak:

Контрольная сумма считается не верно, если в массиве есть 0 то может быть ошибка

Вариант Никитина как раз на такой ошибке работает. 

Да, Вы правы. Только Никитин выбрасывал дополнительно и нулевые элементы. Поэтому его код и выглядел как ошибочным. На самом деле решалась изначально поставленная Вами задача.
Если задокументировать у него проверку на нулевые элементы, то результат одинаковый:

2018.11.14 13:50:34.481 ArrayDeleteValue (BTCUSD,M15)   вариант Pastushak: Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 133765 микросекунд
2018.11.14 13:50:34.486 ArrayDeleteValue (BTCUSD,M15)   вариант Korotky:   Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 2330 микросекунд
2018.11.14 13:50:34.489 ArrayDeleteValue (BTCUSD,M15)   вариант Fedoseev:  Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 1840 микросекунд
2018.11.14 13:50:34.492 ArrayDeleteValue (BTCUSD,M15)   вариант Semko:     Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 777 микросекунд
2018.11.14 13:50:34.497 ArrayDeleteValue (BTCUSD,M15)   вариант Pavlov:    Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 2818 микросекунд
2018.11.14 13:50:34.503 ArrayDeleteValue (BTCUSD,M15)   вариант Nikitin:   Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 3922 микросекунд
2018.11.14 13:50:34.510 ArrayDeleteValue (BTCUSD,M15)   вариант Vladimir:  Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 4239 микросекунд
2018.11.14 13:50:34.519 ArrayDeleteValue (BTCUSD,M15)   вариант Peter:     Контрольная сумма = 7192.975450836821; элементов - 998993; время выполнения = 7307 микросекунд
2018.11.14 13:50:34.522 ArrayDeleteValue (BTCUSD,M15)   вариант Kuznetsov: Контрольная сумма = 7185.677992388435; элементов - 998993; время выполнения = 683 микросекунд

Повторюсь, что сейчас контрольная сумма учитывает порядок элементов, раньше не учитывала. 

Файлы:
 
Да ну его усе. Я вот пивко довариваю. К НГ ~25 литров будет готово. Вот это дело, а вы все о массивах
 
Nikolai Semko:

Да, Вы правы. Только Никитин выбрасывал дополнительно и нулевые элементы. Поэтому его код и выглядел как ошибочным. На самом деле решалась изначально поставленная Вами задача.
Если задокументировать у него проверку на нулевые элементы, то результат одинаковый:

Повторюсь, что сейчас контрольная сумма учитывает порядок элементов, раньше не учитывала. 

Кстати, если порядок очень важен, то можно в мой вариант добавить ArraySort в конце, заодно глянуть насколько ArraySort вообще эффективен. 

 

Меня сейчас интересует другой вопрос, на который не могу найти ответа.
Может кто-то сможет объяснить, почему такой вариант из кода Кузнецова:

    for(;;)
     {
      while(arr[i]!=x && i<j) i++;
      while(arr[j]==x && i<j) j--;
      if(i<j)
        {
         arr[i++]=arr[j--];
        }
      else break;
     }

работает более чем в два раза быстрее, чем такой, делающий абсолютно тоже самое:

   while(i<j)
     {
      if(arr[i]==x)
         if(arr[j]!=x) arr[i++]=arr[j--];
      else j--;
      else i++;
     }

Что за чудеса компилятора?
Неужели для такой конструкции:

while(arr[i]!=x && i<j) i++;

компилятор находит какую то особенную ассемблерную команду поиска для процессора?
Кто-нибудь силен в современных командах процессора?

 
Maxim Kuznetsov:

Кстати, если порядок очень важен, то можно в мой вариант добавить ArraySort в конце, заодно глянуть насколько ArraySort вообще эффективен. 

Пробовал я с ним. Довольно затратная функция выходит. Хотя после нее выкидывать проще. Все нужные подряд идут.


Nikolai Semko:

Да, Вы правы. Только Никитин выбрасывал дополнительно и нулевые элементы. Поэтому его код и выглядел как ошибочным. На самом деле решалась изначально поставленная Вами задача.
Если задокументировать у него проверку на нулевые элементы, то результат одинаковый:

Да почти любую функцию под это дело можно подогнать. Вот моя последняя (чисто экспериментальная была, но похоже и одна из самых менее затратных.)
template<typename T>
int arrayFilter(T &data[],const T value=NULL)
  {
     int s, _s = s = ArraySize(data);
     bool result = false;
     
     for(int i=0, j=0; i<_s; i++)
     {
          if( data[i] == value || data[i] == NULL )
          {
               result = true;
               s--;
               continue;
          }
          if( result )
               data[j] = data[i];
          j++;
     }
     
     if(s < _s)
          ArrayResize(data, s);
     
     return s;
  }
 
Nikolai Semko:

:

работает более чем в два раза быстрее, чем такой, делающий абсолютно тоже самое:


оптимизатор непричём -  сравнений меньше в 2 раза..

Причина обращения: