Убрать из Массива нулевые значения - страница 4

 

Petros Shatakhtsyan:

void OnStart()
  {
   int src[];  // исходный динамический массив
   ArrayResize(src,8);  // задаем размерность
   src[0]=1; src[1]=4; src[2]=2; src[3]=0; src[4]=2; src[5]=0; src[6]=2; src[7]=0; // инициализируем исходный массив
   int size=ArraySize(src); // выясняем размерность, если не известна
   int j=-1;
   for(int i=0;i<size;i++)
     {
      if(j<0) {if(src[i]==0) j=i;}
      else if(src[i]!=0) {src[j]=src[i]; j++;}
     }
   ArrayResize(src,j);
// Проверяем правильность выполнения
   string s="";
   for(int i=0;i<j;i++) s+=IntegerToString(src[i])+"  ";
   Print(s);
  }


void OnStart()
  {
   int src[]={1,4,2,0,2,0,2,0};  // исходный массив
   int size=ArraySize(src);
   int src2[];
   ArrayResize(src2,size);
   int i=0,j;
   while(i<size && src[i]!=0) i++;
   ArrayCopy(src2,src,0,0,i);
   if(i==size) 
     {
      Print(" Массив не содержит нулей");
      return;
     }
   j=i;
   for(;i<size;i++)
     {
      if(src[i]!=0) {src2[j]=src[i]; j++;}
     }
   ArrayResize(src2,j);
// Печатаем новый массив
   string s="";
   for(i=0;i<j;i++) s+=IntegerToString(src2[i])+"  ";
   Print(s);
  }

Это "произведение" искусства, используя 3 цикла.

Кто больше ?


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

Alexey Viktorov:
 Я извиняюсь, но такая запись 

  int src[];  // исходный динамический массив
   ArrayResize(src,8);  // задаем размерность
   src[0]=1; src[1]=4; src[2]=2; src[3]=0; src[4]=2; src[5]=0; src[6]=2; src[7]=0; // инициализируем исходный массив

вместо такой

double src[]={1,4,2,0,0,5,0,3,0};

говорит о грамотности программиста. С такими знаниями надо учиться, а не учить.


В моем примере я проинициализировал динамический массив. А вы привели пример инициализации статического массива. Над статическим массивом невозможно будет потом применить функцию ArrayResize, а я ее использовал дальше по коду. В последнем моем примере, если вы обратите внимания, где я предлагаю вариант решения через создания нового динамического массива, я как раз использую ваш вариант инициализации исходного массива.

Так, например, в этом примере этого обсуждения была допущена эта ошибка и компилятор в нем выдает сообщение: cannot be used for static allocated array ( P.S. : как выяснилось позже при компиляции в MQL5)

 
Nikolai Semko:

Над статическим массивом невозможно будет потом применить функцию ArrayResize, а я ее использую дальше по коду. 

Судя по справке да, ArrayResize не применима к статическим массивам, но вот на практике...

Ваш же пример но со статическим массивом работает нормально


void OnStart()
{
   int src[]={1,4,2,0,2,0,2,0};
   int size=ArraySize(src); // выясняем размерность, если не известна
   int j=-1;
   for(int i=0;i<size;i++)
     {
      if(j<0) {if(src[i]==0) j=i;}
      else if(src[i]!=0) {src[j]=src[i]; j++;}
     }
   ArrayResize(src,j);
// Проверяем правильность выполнения
   string s="";
   for(int i=0;i<j;i++) s+=IntegerToString(src[i])+"  ";
   Print(s);
}
 
Sergey Kolemanov:

Судя по справке да, ArrayResize не применима к статическим массивам, но вот на практике...

Ваш же пример но со статическим массивом работает нормально

void OnStart()
{
   int src[]={1,4,2,0,2,0,2,0};
   int size=ArraySize(src); // выясняем размерность, если не известна
   int j=-1;
   for(int i=0;i<size;i++)
     {
      if(j<0) {if(src[i]==0) j=i;}
      else if(src[i]!=0) {src[j]=src[i]; j++;}
     }
   ArrayResize(src,j);
// Проверяем правильность выполнения
   string s="";
   for(int i=0;i<j;i++) s+=IntegerToString(src[i])+"  ";
   Print(s);
}

Я всё понял. Этот код работает и на MQL4 и на MQL5. Вы компилируете на MQL4 и все ОK. Я же компилировал на MQL5, а там ругается на статический массив. В дальнейшем, конечно же, необходимо всегда делать оговорку про используемый язык (четверка или пятерка), чтобы не возникало подобных недопониманий. ))
Спасибо.

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

Но это уже вопрос разработчикам...

 

Детский сад в действии.
Уже не в первый возникает проблема с отсутствием базового понимания структур данных (list, array, map, set, hash,....) у значительной части активного на форуме сообщества.
В MQL язык ввели адекватный template, но, к сожалению, адаптированной стандартной библиотеки по прежнему нет.
В общем - а воз и ныне нем.

 
Nikolai Semko:
Я всё понял. Этот код работает и на MQL4 и на MQL5. Вы компилируете на MQL4 и все ОK. Я же компилировал на MQL5, а там ругается на статический массив. В дальнейшем, конечно же, необходимо всегда делать оговорку про используемый язык (четверка или пятерка), чтобы не возникало подобных недопониманий. ))
Спасибо.

Да, компилировал и проверял в четвёрке...

 
Sergey Dzyublik:

Детский сад в действии.
Уже не в первый возникает проблема с отсутствием базового понимания структур данных (list, array, map, set, hash,....) у значительной части активного на форуме сообщества.
В MQL язык ввели адекватный template, но, к сожалению, адаптированной стандартной библиотеки по прежнему нет.
В общем - а воз и ныне нем.


Конечно еще много предстоит сделать. Но все равно разработчики красавцы. Просто всего очень много и не все сразу. Задача ведь реально очень объемная. Лично я верю в то, что MQL завоюет мир. 

Я недавно спрашивал у одной американской конторы, которая сидит на многих платформах и недавно приобрела лицензию MT5, "Какая лучшая платформа на сегодняшний день в мире для автотрейдинга?"  На что получил ответ: "Пожалуй с учетом всех нюансов MT5" .
А ведь по сути ребята из MQ только набирают обороты.

 
Nikolai Semko:   Лично я верю в то, что MQL завоюет мир.

Нас он уже завоевал

 
STARIJ:

Нас он уже завоевал


вот так всегда, работаешь с человеком, а потом оказывается он "воюет", "завоевывает", "побеждает" (

 

Честно все изучал и пробовал , остановился на одном из Вариантов , подогнал под свою задачу . Что то не получается .

Трудно дается , это обучение 

Нужно убрать нули из буфера SWO , причем по мере его наполнения . Укажите пожалуйста на ошибку , Заранее спасибо ! ,

Судя По выводу цифр в журнал эксперта , нули остаются ...

MQL5

//+------------------------------------------------------------------+
//|                                                   SWING_LINE.mq5 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots   1
//--- plot Label1
#property indicator_label1  "Swing_Line"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input double    points=0.0050;
input double    begin_price_level=1.1250;
//--- indicator buffers
double         Swing_LineBuffer[] , delta_up [] ,delta_down[] ,kup [] ,kdown [], SWO [] ;


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Swing_LineBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,kup,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,kdown,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,delta_up,INDICATOR_CALCULATIONS);
   SetIndexBuffer(4,delta_down,INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,SWO,INDICATOR_CALCULATIONS);
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_SOLID);
   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int  bar =1 , i = 0,j=1;
   // начальный уровень цены от которой идет отсчет , уровень на нулевом баре
   Swing_LineBuffer [0] = begin_price_level ;
   j=bar;
   //поехали считать слева направо
   for(bar = 1; bar < rates_total; bar++) 
   //Высчитаем сколько на баре цена ушла вверх от заданного уровня  предидущего бара
   {delta_up[bar] = high[bar]- Swing_LineBuffer [bar -1];
   //найдем кратность прохода цены поинтам заданным , если цена не прошла кратно одному блоку размером в points то сбросится переменная до ноля
   kup[bar] = floor(delta_up[bar] / points);
   //Высчитаем сколько на баре цена ушла вниз от заданного уровня  предидущего бара
   delta_down[bar] = Swing_LineBuffer [bar -1]-low[bar];
   //найдем кратность прохода цены поинтам заданным , если цена не прошла кратно одному блоку размером в points то сбросится до  ноля
   kdown[bar] =floor(delta_down[bar] / points) ;  
    // если есть движение вверх кратное одному блоку points тогда , рисуем новый уровень индикатора наверх
   if (kup[bar] >=1) {Swing_LineBuffer[bar] = Swing_LineBuffer[bar-1] + (kup[bar]*points) ; SWO [bar] = 1;}
       //если есть движение вниз кратное одному блоку points тогда , рисуем новый уровень индикатора вниз
   else   
   if (kdown[bar] >=1) {Swing_LineBuffer [bar] = Swing_LineBuffer[bar-1] - (kdown[bar]*points) ;SWO [bar] = -1;}
   // нет движения кратного блоку points тогда индикатор на прежнем уровне 
   else  
   {Swing_LineBuffer[bar] = Swing_LineBuffer[bar-1] ;
   SWO [bar] = 0 ;}
  
  //оптимизируем кривую убирая нули и отвязывая от оси времени
   if(SWO[bar]!=0) {SWO[j]=SWO[bar]; j++;}
   else continue ;
   ArrayResize(SWO,j);
   string s="";
   s+=IntegerToString(SWO[j])+"  ";
   Print(s);
   }
   
   
     
       
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
LookingFor:

Честно все изучал и пробовал , остановился на одном из Вариантов , подогнал под свою задачу . Что то не получается .

Трудно дается , это обучение 

Нужно убрать нули из буфера SWO , причем по мере его наполнения . Укажите пожалуйста на ошибку , Заранее спасибо ! ,

Судя По выводу цифр в журнал эксперта , нули остаются ...

MQL5

у вас одновременно и

   SetIndexBuffer(5,SWO,INDICATOR_CALCULATIONS);

и

   if(SWO[bar]!=0) {SWO[j]=SWO[bar]; j++;}
   else continue ;
   ArrayResize(SWO,j)

таких зверей небывает :-)

на каждом баре терминал САМ добавит пустое значение в ваш массив - он же индекс; вам ещё повезло что в текущем билде ArrayResize на индексном буфере не убивает индикатор наглухо

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