Limpar um conjunto de elementos definidos - página 8

 
Eu não sei o que é o mt4, ele nem vai funcionar com win10, então eu acho que isso é uma coisa boa
 
Maxim Dmitrievsky:
Eu não sei o que é o mt4, ele não vai nem rodar em win10, eu acho que isso é uma coisa boa
Bem dito:)
 

Eu afinei a matriz.

void OnStart()
{
     long array[], arr[] = {1, 2, 3, 6, 9, 5, 6, 3, 25, , , 6, 8, NULL, 7, NULL, 4, 45};
     ArrayCopy(array, arr); 
//--
  #ifdef __MQL5__
     Print( arrayFilter(array, array[2]) );
     ArrayPrint( array );
  #else
     string s = arrayFilter(array, array[2]) + " {";
     
     for(int i=0; i<ArraySize(array); i++)
     {
          s += array[i];
          if(i<ArraySize(array)-1)
               s += ", ";
     }
     
     Print( s+" }" );
  #endif
}
//---------------------------------------------------------------
template<typename T>
int arrayFilter(T &data[], const T value)
{
     int d = ArraySize(data), j = 0, y = 0;
     
     for(int i=0; i<d; i++, y++)
     {
          if(j>0)
               data[y] = data[y + j];
          
          if(data[i] == value || data[i] == NULL)
          {
               y--;
               j++;
          }
     }
  
     if(d > y)
          ArrayResize(data, y);
     
     return y;
}

Eu tive que usar o ArrayCopy , porquea MQL5 jurou que a matriz era estática.


 
Nikolai Semko:

Se é um concurso de velocidade, vou oferecer minha própria variante.

Sua variante é de fato a mais rápida, mas contém um bug: se todos os elementos de um array forem iguais a um filtro, sua função sairá do array.

Vou oferecer minha própria variante, ela é um pouco mais lenta que a sua:

int ArrayModify(int &a[],const int v)
  {
   int size=ArraySize(a)-1;
   int j=0;
   int total=size;
   for(int i=0;i<size;i++)
     {
      while(a[i+j]==v && j<total)
        {
         j++;
         size--;
        }
      a[i]=a[i+j];
     }
   size=ArrayResize(a,size);
   return(size);
  }


2018.11.13 17:16:38.618 massiv v1 (EURUSD,M1) teste my=1512090
2018.11.13 17:16:40.083 massiv v1 (EURUSD,M1) teste alien=1464941

 
Vasiliy Sokolov:

Você vem fazendo esse tipo de pergunta há vários anos. Você já aprendeu muito? Desculpe, mas é óbvio que você ainda está no nível de bytes e arrays elementares.

A questão em si é formulada incorretamente. A tarefa não é remover valores duplicados (tarefa de nível GCE), mas em algo muito maior, você deve atualizar a lista de itens válidos. Se assim for, a questão deve soar completamente diferente. Você confunde e engana os participantes e, antes de tudo, a si mesmo: imponha aos participantes a solução errada em princípio e peça para torná-la eficaz.

Eu não faço programação por programação, não tenho nenhum objetivo de me tornar um mega-programador e de ser esperto em fóruns.

O que você não entende na pergunta: Limpar um conjunto de elementos definidos?

 
Sergey Pavlov:

Sua variante é de fato a mais rápida, mas contém um bug: se todos os elementos de um array forem iguais a um filtro, sua função sairá do array.

Vou sugerir minha variante, é um pouco mais lenta que a sua:


2018.11.13 17:16:38.618 massiv v1 (EURUSD,M1) teste my=1512090
2018.11.13 17:16:40.083 massiv v1 (EURUSD,M1) teste alien=1464941

Sim, obrigado. Corrigido.

int ArrayDeleteVal(int &a[],const int val) // вариант Semko
  {
   int size=ArraySize(a);
   int i=0,start,s,count;
   while(i<size && a[i]!=val) i++; // ищем первый элемент массива со значением val
   if(i==size) return size;
   start=i; i++;  
   while(i<size && a[i]==val) i++; // ищем элемент массива со значением, не равным val
   if(i==size) {ArrayResize(a,0); return 0;}
   s=i; i++;
   while(true)
     {
      while(i<size && a[i]!=val) i++; // ищем элемент массива со значением val
      count=i-s;
      if(count>6) { ArrayCopy(a,a,start,s,count); start+=count;} // если нужно скопировать более 6 элементов, то имеет смысл воспользоваться ArrayCopy
      else for(; s<i; start++,s++) a[start]=a[s];                // иначе простой цикл
      if(i==size) break;
      i++;
      while(i<size && a[i]==val) i++; // ищем элемент массива со значением, не равным val
      if(i<size) s=i; else break;
      i++;
     }
   if(start<size) ArrayResize(a,start); else start=size;
   return(start);
  }

Somente você também tem um erro em algum lugar, porque o checksum não coincide porque falta um elemento em algum lugar. Não funcionou onde.

2018.11.13 10:07:27.757 ArrayDeleteValue (EURUSD,D1)    вариант Pastushak: Контрольная сумма = 495782577; элементов - 999027; время выполнения = 156757 микросекунд
2018.11.13 10:07:27.761 ArrayDeleteValue (EURUSD,D1)    вариант Korotky:   Контрольная сумма = 495782577; элементов - 999027; время выполнения = 2338 микросекунд
2018.11.13 10:07:27.764 ArrayDeleteValue (EURUSD,D1)    вариант Fedoseev:  Контрольная сумма = 495782577; элементов - 999027; время выполнения = 1839 микросекунд
2018.11.13 10:07:27.766 ArrayDeleteValue (EURUSD,D1)    вариант Semko:     Контрольная сумма = 495782577; элементов - 999027; время выполнения = 782 микросекунд
2018.11.13 10:07:27.770 ArrayDeleteValue (EURUSD,D1)    вариант Pavlov:    Контрольная сумма = 495781718; элементов - 999026; время выполнения = 2886 микросекунд
2018.11.13 10:07:27.773 ArrayDeleteValue (EURUSD,D1)    вариант Nikitin:   Контрольная сумма = 495782577; элементов - 999027; время выполнения = 2355 микросекунд
Arquivos anexados:
 

Ajustou-o removendo passagens desnecessárias

void OnStart()
{
     long array[], arr[] = {1, 2, 3, 6, 9, 5, 6, 3, 25, , , 6, 8, NULL, 7, NULL, 4, 45};
     ArrayCopy(array, arr);
//--
  #ifdef __MQL5__
     Print( arrayFilter(array, (long)3) );
     ArrayPrint( array );
  #else
     string s = arrayFilter(array, (long)3) + " {";
     
     for(int i=0; i<ArraySize(array); i++)
     {
          s += array[i];
          if(i<ArraySize(array)-1)
               s += ", ";
     }
     
     Print( s+" }" );
  #endif
}
//---------------------------------------------------------------
template<typename T>
int arrayFilter(T &data[], const T value=NULL)
{
     int d = ArraySize(data), y = 0;
     
     for(int i=0, j=0; i<d; i++, y++)
     {
          bool res = false;
          while(data[i] == value || data[i] == NULL)
          {
               res = true;
               j++;
            //---
               if(i+1==d)
                    break;
               if(data[i+1] == value || data[i+1] == NULL)
                    i++;
               else
                    break;
          }
          
          if(j>0)
          {
               if(d==y+j)
                    break;
               data[y] = data[y + j];
          }
          if(res)
               y--;
     }
  
     if(d > y)
          ArrayResize(data, y);
     
     return y;
}
 
Nikolai Semko:
Em ambos os casos, cada elemento é arrastado, no máximo, uma vez.

Sim, desculpe, uma vez de fato. Eu esperava que alguém estivesse interessado na abordagem do SGBD e checá-lo, não esperasse. Tinha que ser eu mesmo a fazê-lo.

int ArrayDelV (int &a[],const int val) { // вариант Vladimir
bool Flags[]; // массив пометок на удаление
int N, NewN, i, j;
N=ArraySize(a);
ArrayResize(Flags,N);
//if (ArrayInitialize(Flags,false)!=N) return(-1);
NewN=N; // Сколько останется
for (i=0;i<N;i++) {if (a[i]==val) {Flags[i]=true; NewN--;}}
j=0;
for (i=0;i<N;i++) {if (Flags[i]) {a[j]=a[i]; j++;}}
ArrayResize(a,NewN);
return(NewN);
}

Inserido ArrayDeleteValue.mq5 em seu verificador, ele é duas vezes pior que o seu. Pensei no motivo e fixei duas linhas para que um terço dos itens fosse removido em vez de 0,1%.

   for(int i=0; i<1000000;i++) arr[i]=rand()%3;// 1000; //генерируем исходный массив случайными значениями от 0 до 1000
   int Value=rand()%3; // 1000; // значение, которое нужно удалить из массива

Foi assim que tudo aconteceu:

2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Pastushak: Checksum = 333586; elementos - 667421; tempo de execução = 108521 microssegundos
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Korotky: Checksum = 333586; elementos - 667421; tempo de execução = 5525 microssegundos
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Fedoseev: Checksum = 333586; elementos - 667421; tempo de execução = 4879 microssegundos
2018.11.13 19:45:22.164 Del (GBPUSD.m,H1) variante Semko: Checksum = 333586; elementos - 667421; tempo de execução = 14479 microssegundos
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Pavlov: Checksum = 998744; elementos - 667421; tempo de execução = 0 microssegundos
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Nikitin: Checksum = 333586; elementos - 667421; tempo de execução = 5759 microssegundos
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Vladimir: Checksum = 333586; elementos - 667421; tempo de execução = 1542 microssegundos

A variante de Pavlov tinha um erro, tive que comentar.

Conclusão: calcular endereços em uma matriz com uma distância arbitrária entre seus números ainda é pior do que processar elementos em uma linha, em uma determinada etapa, muito menos na etapa 1, o compilador pode otimizá-la.

Os compiladores P.S. Pascal e Delphi da Borland fazem com que, em tempo de execução, a variável loop não importe (em memória), ela seja colocada em algum lugar nos registros da CPU.

 
Vladimir:

Sim, desculpe, uma vez de fato. Eu esperava que alguém estivesse interessado na abordagem do SGBD e checá-lo, não esperasse. Tinha que ser eu mesmo a fazê-lo.

Inserido ArrayDeleteValue.mq5 em seu verificador, ele é duas vezes pior que o seu. Pensei nos motivos e fixei duas linhas para que um terço dos itens fosse eliminado em vez de 0,1%.

Foi assim que tudo aconteceu:

2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Pastushak: Checksum = 333586; elementos - 667421; tempo de execução = 108521 microssegundos
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Korotky: Checksum = 333586; elementos - 667421; tempo de execução = 5525 microssegundos
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) variante Fedoseev: Checksum = 333586; elementos - 667421; tempo de execução = 4879 microssegundos
2018.11.13 19:45:22.164 Del (GBPUSD.m,H1) variante Semko: Checksum = 333586; elementos - 667421; tempo de execução = 14479 microssegundos
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Pavlov: Checksum = 998744; elementos - 667421; tempo de execução = 0 microssegundos
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Nikitin: Checksum = 333586; elementos - 667421; tempo de execução = 5759 microssegundos
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) variante Vladimir: Checksum = 333586; elementos - 667421; tempo de execução = 1542 microssegundos

A variante de Pavlov tinha um erro, tive que comentar.

Conclusão: calcular endereços em uma matriz com uma distância arbitrária entre seus números ainda é pior do que processar itens em fila em uma determinada etapa, ainda mais na etapa 1, o compilador pode otimizá-la.

Os compiladores P.S. Pascal e Delphi da Borland fazem com que, em tempo de execução, a variável loop não importe (em memória), ela seja colocada em algum lugar nos registros da CPU.

A versão de Pavlov foi corrigida.
Seus valores são estranhos. Talvez você tenha executado o script depois de traçar o perfil ou depurar sem recompilar o código?
É assim que funciona para mim:

2018.11.13 12:35:38.633 ArrayDeleteValue (EURUSD,D1)    вариант Pastushak: Контрольная сумма = 496494849; элементов - 999011; время выполнения = 131964 микросекунд
2018.11.13 12:35:38.636 ArrayDeleteValue (EURUSD,D1)    вариант Korotky:   Контрольная сумма = 496494849; элементов - 999011; время выполнения = 2310 микросекунд
2018.11.13 12:35:38.639 ArrayDeleteValue (EURUSD,D1)    вариант Fedoseev:  Контрольная сумма = 496494849; элементов - 999011; время выполнения = 1834 микросекунд
2018.11.13 12:35:38.641 ArrayDeleteValue (EURUSD,D1)    вариант Semko:     Контрольная сумма = 496494849; элементов - 999011; время выполнения = 773 микросекунд
2018.11.13 12:35:38.645 ArrayDeleteValue (EURUSD,D1)    вариант Pavlov:    Контрольная сумма = 496494849; элементов - 999011; время выполнения = 2815 микросекунд
2018.11.13 12:35:38.648 ArrayDeleteValue (EURUSD,D1)    вариант Nikitin:   Контрольная сумма = 496494849; элементов - 999011; время выполнения = 2475 микросекунд
2018.11.13 12:35:38.653 ArrayDeleteValue (EURUSD,D1)    вариант Vladimir:  Контрольная сумма = 496656342; элементов - 999011; время выполнения = 3608 микросекунд

E em sua versão gera um checksum incorreto. E criar uma matriz adicional não traz nenhum benefício, ao contrário, retarda o processo e consome recursos adicionais.

Arquivos anexados:
 
Em essência, todos os algoritmos são os mesmos. Todos modificam o array elemento por elemento, e todos se esforçam pela variante Fedoseev, porque ela não tem nada desnecessário.
Somente no meu caso é feito em blocos usando o ArrayCopy, portanto há uma vantagem de velocidade.
Razão: