Genel sınıflar kütüphanesi - hatalar, açıklamalar, sorular, kullanım özellikleri ve öneriler

 

6 Aralık 2017'den bu yana, MetaTrader 5 'in standart teslimatı, veri depolama ve alma için verimli algoritmalar uygulayan sözde Genel sınıfları içermektedir. Bu konu başlığı, bu sınıfları, onlarla çalışma örneklerini ve çalışmalarını iyileştirmek için önerileri açıklamak için oluşturulmuştur.

Jeneriknedir? Jenerik sınıflar, özel veri türlerini depolayabilen özel şablon sınıflardır. Tür tanımlaması derleme zamanında gerçekleştirilir ve bu da yüksek performans sağlar.

Neden Jenerik? Kural olarak, acemi programcılar yalnızca bir koleksiyon türüne aşinadır: dizi. Ancak bir dizi ile çalışmanın verimsiz olduğu birçok görev vardır. Bir milyon benzersiz tanımlayıcıdan oluşan bir dizimiz olduğunu düşünün, örneğin bin sipariş. Bu bin sipariş içinde N numaralı bir sipariş olup olmadığını nasıl kontrol edebiliriz? Genel sınıflardan birini kullanırsak, bu görev neredeyse anında, aramanın yapılacağı eleman sayısına bağlı olmayan sabit bir süre için gerçekleştirilebilir. Genel koleksiyondaki doğru algoritmanın bir programcı tarafından icat edilen algoritmadan daha hızlı olabileceği başka görevler de vardır.

Genel algoritmalar. Aşağıda, ne yaptıklarının kısa bir açıklaması ile birlikte genel sınıfların bir tablosu bulunmaktadır:

SınıfAçıklama
CArrayList.Otomatik boyut yeniden bölümleme özelliğine sahip bir dizi. Bir dizinin dışına çıkmayı kontrol etmek zorunda kalmadan diziden yararlanmanızı sağlar.
CHashMapBir anahtar-değer kümesi. Öğelerin anahtarlarına göre verimli bir şekilde eklenmesine, alınmasına ve aranmasına izin verir. Anahtar benzersiz olmalıdır. Örneğin, CHashMap, numaranın anahtar olarak kullanıldığı belirli bir numaraya sahip bir siparişi anında bulabilir.
CHashSetBenzersiz öğelerden oluşan bir küme. CHashMap ile aynı şeyleri yapmaya izin verir, ancak bir anahtar gerektirmez. Bu koleksiyonda saklanan öğeler tekrarlanmamalıdır. Ayrıca bir öğenin anında aranmasına, alınmasına ve eklenmesine izin verir.
CLinkedListÇift bağlantılı bir liste. Öğelerin kolayca eklenmesine ve silinmesine izin verir. Ancak, istenen öğeyi bulmak için listedeki öğe sayısına doğrusal olarak bağlı zaman alır.
CQueueYığın. FIFO tipi bir kuyruk düzenler
CStackYığın. LIFO tipi bir kuyruk düzenler
CRedBlackTreeRedBlackTree. Öğeleri hızlı bir şekilde (logaritmik zamanda) eklemenizi, çıkarmanızı ve bulmanızı sağlar. CHashMap ve CHashSet'in aksine, more than, less than, between gibi ek ilişki algoritmalarının verimli bir şekilde uygulanmasına izin verir.
CSortedMapAnahtara göre sıralanmış küme. Anahtar-değer değerlerini depolar. Bu durumda, anahtar sıralanır.
CSortedSetDeğere göre sıralanmış bir küme. Sıralı bir değerler kümesini saklar.

Daha sonra devam edeceğiz ve bu sınıfların uygulama özelliklerine bakacağız.

 
Vasili Sokolov :

Bir milyon benzersiz tanımlayıcı dizimiz olduğunu, örneğin bin sipariş olduğunu hayal edin. Bu bin siparişte N numaralı bir sipariş olup olmadığı nasıl kontrol edilir? Genel sınıflardan birini kullanırsanız, bu görev , aramanın gerçekleştirileceği öğelerin sayısına bağlı olmayacak şekilde sabit bir sürede neredeyse anında tamamlanabilir.

Konuya tamamen yabancı. Ancak vurgulanan, mantıksız geliyor.

 

Ne yazık ki, kütüphane yeni çıktı ve hala nemli. İlk hatayı zaten buldum (hataları bir işaretleyici ile vurgulayacağım, bu önemli):

CSortedSet'te hata:

 //+------------------------------------------------------------------+
//| Class CSortedSet<T>.                                             |
//| Usage: Represents a collection of objects that is maintained in  |
//|        sorted order.                                             |
//+------------------------------------------------------------------+
template < typename T>
class CSortedSet: public ISet<T>
  {
   ...
   bool               TryGetMin(T &min)    { return (m_tree. TryGetMin (min)); }
   bool               TryGetMax(T &max)    { return (m_tree. TryGetMin (max)); }
   ...
  }

TryGetMax yöntemi, maksimum öğeyi değil, tıpkı TryGetMin gibi minimum öğeyi döndürür

 
fxsaber :

... Ama vurgulananlar mantıksız geliyor.

Niye ya?

 
Vasili Sokolov :

Niye ya?

Karma yapın, artan düzende sıralayın. Ancak her durumda arama olacaktır.

 
fxsaber :

Konuya tamamen yabancı. Ancak vurgulanan, mantıksız geliyor.

ortalama O(1) süresi O(n)'den daha kötüdür ve performans büyük ölçüde karmaya bağlıdır.
 
fxsaber :

Hash yap...

Terminolojiyi tanımlayalım. Hiçbir şey anlık değildir. Herhangi bir işlem zaman alır. Anında konuştuğumda, acemi programcıların beni anlaması için basitleştiririm. Açıkçası, birkaç karmaşıklık sınıfı vardır, ilgileneceğimiz ana olanlar şunlardır:

  • Sabit karmaşıklık c O(1) .
  • Logaritmik: O(log n) ile .
  • Doğrusal: c O(n) .
  • Doğrusal olmayan yürütme süresi gerektiren algoritmalar.

C - işaretini kasıtlı olarak, hash ve diğer teknik manipülasyonları hesaplarken ortaya çıkan bir tür sabit olarak tanıttım. Ancak bu durumda, sabit c'yi optimize etme tartışması bu konuya kapalıdır. Biz sadece jenerik sınıflarla ve onların pratikteki uygulamalarıyla ilgileniyoruz.

 
fxsaber :

Karma yapın, artan düzende sıralayın. Ancak her durumda arama olacaktır.

birleştirici :
ortalama O(1) süresi O(n)'den daha kötüdür ve performans büyük ölçüde karmaya bağlıdır.

+

ps Örnek olarak, CHashMap ile çalışmak yanlışsa, bu performansın O (n) 'ye düşeceği bir örnek vereceğim.

 

İsimleri basitleştirmeyi öneriyorum - onları daha mantıklı hale getirmek için. Örnek, mql5'te CarrayList hala Array veya List'tir, her ikisinin de bir uygulaması var mı?

Bütün bunlar soruları ve yanlış anlamaları kışkırtır. IMHO, C # veya Java altında değil, stl altında biçmek gerekir. Veya C'den önce kaldırın, sadece ArrayList olsun.


Normal adlar yaparsanız:

- Okunabilirlik önemli ölçüde artacak

- kendi özel mql5 stilini çizecek

- yeni başlayanlar kodda hemen gezinebilecekler (stl standarda dahil olduğundan)

 
Vasili Sokolov :

...

Mümkünse, örneğin binlerce işlem arasında arama yapmakla ilgili örnekler.
Neden: