Verilen eleman(lar)ın bir dizisini temizleme - sayfa 8

 
MT4'ün ne olduğunu bilmiyorum, win10'da çalıştırmak bile istemedi, Allah'a şükür bence
 
Maxim Dmitrievsky :
MT4'ün ne olduğunu bilmiyorum, win10'da çalıştırmak bile istemedi, Allah'a şükür bence
iyi dedin :)
 

Yığın için bükülmüş.

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

ArrayCopy'yi dışarı sürmek zorunda kaldım . MQL5'te dizinin statik olduğuna lanet ettim.


 
Nikolai Semko :

Peki, hız açısından böyle bir içki yarışması zaten gittiyse, o zaman kendi versiyonumu sunacağım ...

Sürümünüz gerçekten en hızlısı, ancak bir hata içeriyor: dizinin tüm öğeleri filtreye eşitse, işleviniz dizinin dışında çöküyor.

Kendi versiyonumu sunacağım, hızı sizinkinden biraz daha düşük:

 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 masif v1 (EURUSD,M1) testi madeni=1512090
2018.11.13 17:16:40.083 masif v1 (EURUSD,M1) uzaylı testi=1464941

 
Vasiliy Sokolov :

Bu soruları yıllardır soruyorsunuz. Çok şey öğrendin mi? Üzgünüz, ancak ikinizin de bayt düzeyi ve temel dizilerle uğraştığınız ve orada kaldığınız açık.

Sorunun kendisi yanlış ifade edilmiştir. Görev, yinelenen değerleri (OGE seviyesinin görevi) kaldırmak değil, daha fazlası, görünüşe göre geçerli öğeler listesini güncelliyorsunuz. Eğer öyleyse, o zaman soru kulağa oldukça farklı gelmelidir. Katılımcıları ve her şeyden önce kendinizi şaşırtıyorsunuz ve yanıltıyorsunuz: İlke olarak katılımcılara yanlış kararı empoze edin ve onlardan bunu etkili hale getirmelerini isteyin.

Programlama yapmak için programlama yapmıyorum, forumlarda mega programcı olmak ve akıllı olmak gibi bir amacım yok.

Soruda net olmayan şey: Diziyi verilen öğelerden temizle?

 
Sergey Pavlov :

Sürümünüz gerçekten en hızlısı, ancak bir hata içeriyor: dizinin tüm öğeleri filtreye eşitse, işleviniz dizinin dışında çöküyor.

Kendi versiyonumu sunacağım, hızı sizinkinden biraz daha düşük:


2018.11.13 17:16:38.618 masif v1 (EURUSD,M1) testi madeni=1512090
2018.11.13 17:16:40.083 masif v1 (EURUSD,M1) yabancı testi=1464941

Evet teşekkür ederim. Düzeltildi.

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

Yalnız sende de bir yerde hata var tk. sağlama toplamı eşleşmiyor, çünkü bir yerde bir elementi kaybeder. Nerede olduğunu anlamadım.

 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 микросекунд
Dosyalar:
 

Düzenlendi, gereksiz geçişler kaldırıldı

 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 :
Her iki durumda da her öğe en fazla bir kez sürüklenir.

Evet, üzgünüm, gerçekten, bir kez. Birinin DBMS'den gelen yaklaşımla ilgileneceğini ve kontrol edeceğini umdum, beklemedim. kendime mecburdum.

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

ArrayDeleteValue.mq5'i denetleyicinize ekledim, iki kez sizinkinden daha kötü çıktı. Sebepleri düşündüm ve içindeki iki satırı düzelttim, böylece öğelerin üçte biri silindi,% 0.1 değil.

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

Şu şekilde çıktı:

2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) Pastushak varyantı: Sağlama toplamı = 333586; elemanlar - 667421; yürütme süresi = 108521 mikrosaniye
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) Korotky varyantı: Sağlama toplamı = 333586; elemanlar - 667421; yürütme süresi = 5525 mikrosaniye
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) Fedoseev varyantı: Sağlama toplamı = 333586; elemanlar - 667421; yürütme süresi = 4879 mikrosaniye
2018.11.13 19:45:22.164 Del (GBPUSD.m,H1) Semko varyantı: Sağlama toplamı = 333586; elemanlar - 667421; yürütme süresi = 14479 mikrosaniye
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) Pavlov varyantı: Sağlama toplamı = 998744; elemanlar - 667421; çalışma zamanı = 0 mikrosaniye
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) Nikitin varyantı: Sağlama toplamı = 333586; elemanlar - 667421; yürütme süresi = 5759 mikrosaniye
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) Vladimir seçeneği: Sağlama toplamı = 333586; elemanlar - 667421; yürütme süresi = 1542 mikrosaniye

Pavlov varyantı bir hata verdi, yorum yapmak zorunda kaldım.

Sonuç: Bir dizideki adresleri, sayıları arasında keyfi bir mesafe ile hesaplamak, belirli bir adımda, özellikle 1. adımda, bir satırdaki öğeleri işlemekten hala daha kötüdür, derleyici bunu optimize edebilir.

PS Pascal ve Delphi için Borland derleyicilerinde, döngü değişkeni döngü yürütme sırasında (bellekte) önemli değildir, işlemci kayıtlarında bir yere yerleştirilir.

 
Vladimir :

Evet, üzgünüm, gerçekten, bir kez. Birinin DBMS'den gelen yaklaşımla ilgileneceğini ve kontrol edeceğini umdum, beklemedim. kendime mecburdum.

ArrayDeleteValue.mq5'i denetleyicinize ekledim, iki kez sizinkinden daha kötü çıktı. Sebepleri düşündüm ve içindeki iki satırı düzelttim, böylece öğelerin üçte biri silindi,% 0.1 değil.

Şu şekilde çıktı:

2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) Pastushak varyantı: Sağlama toplamı = 333586; elemanlar - 667421; yürütme süresi = 108521 mikrosaniye
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) Korotky varyantı: Sağlama toplamı = 333586; elemanlar - 667421; yürütme süresi = 5525 mikrosaniye
2018.11.13 19:45:22.148 Del (GBPUSD.m,H1) Fedoseev varyantı: Sağlama toplamı = 333586; elemanlar - 667421; yürütme süresi = 4879 mikrosaniye
2018.11.13 19:45:22.164 Del (GBPUSD.m,H1) Semko varyantı: Sağlama toplamı = 333586; elemanlar - 667421; yürütme süresi = 14479 mikrosaniye
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) Pavlov varyantı: Sağlama toplamı = 998744; elemanlar - 667421; çalışma zamanı = 0 mikrosaniye
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) Nikitin varyantı: Sağlama toplamı = 333586; elemanlar - 667421; yürütme süresi = 5759 mikrosaniye
2018.11.13 19:45:22.179 Del (GBPUSD.m,H1) Vladimir seçeneği: Sağlama toplamı = 333586; elemanlar - 667421; yürütme süresi = 1542 mikrosaniye

Pavlov varyantı bir hata verdi, yorum yapmak zorunda kaldım.

Sonuç: Bir dizideki adresleri, sayıları arasında keyfi bir mesafe ile hesaplamak, belirli bir adımda, özellikle 1. adımda, bir satırdaki öğeleri işlemekten hala daha kötüdür, derleyici bunu optimize edebilir.

PS Pascal ve Delphi için Borland derleyicilerinde, döngü değişkeni döngü yürütme sırasında (bellekte) önemli değildir, işlemci kayıtlarında bir yere yerleştirilir.

Pavlov'un versiyonu düzeltildi.
Garip değerlerin var. Belki de kodu yeniden derlemeden profil oluşturduktan veya hata ayıklayıcıdan sonra komut dosyasını çalıştırdınız?
Bunu şöyle anlıyorum:

 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 микросекунд

Ve varyantınızda yanlış sağlama toplamı üretir. Ve genel olarak, ek bir dizinin oluşturulması herhangi bir fayda sağlamaz, aksine süreci yavaşlatır ve hatta ek kaynakları tüketir.

Dosyalar:
 
Aslında, tüm algoritmalar aynıdır. Herkes dizi elemanının modifikasyonunu eleman bazında gerçekleştirir ve herkes Fedoseev varyantına yönelir, çünkü onun ekstra bir şeyi yok.
Sadece benim için ArrayCopy kullanan bloklarda oluyor, bu yüzden hız kazancı var.