//+------------------------------------------------------------------+//| CompareFunction.mqh |//| Copyright 2016-2017, MetaQuotes Software Corp. |//| https://www.mql5.com |//+------------------------------------------------------------------+#include <Generic\Interfaces\IComparable.mqh>
//+------------------------------------------------------------------+//| Compares two objects and returns a value indicating whether one |//| is less than, equal to, or greater than the other. |//+------------------------------------------------------------------+int Compare( constbool x, constbool y)
{
if (x>y)
return ( 1 );
elseif (x<y)
return (- 1 );
elsereturn ( 0 );
}
İşlev, küresel düzeyde bildirilir. Bu nedenle, Karşılaştır kullanıcılarıyla bir çakışma var.
'Compare' - function already defined and has body
Adlandırma çakışmalarını azaltmak için Yazar, tüm genel Genel yardımcı işlevleri genel statik yöntemler yapabilir mi?
Alexey Navoykov : Bu şu an için. Her şey bir araya toplandığında, çöküş kaçınılmazdır) Birinin kitaplığını dahil etmek istiyorsanız, o zaman yazarın sizin yaptığınız gibi aynı "ilkel" şekilde, aynı sınıf ve işlev adlarını kullanarak yazdığı ortaya çıkar.
Seni makrolarla yeneceğim, seni makrolarla yeneceğim.
Bir dizi anahtar/değer çifti. Öğeleri anahtarlarına göre verimli bir şekilde eklemenize, almanıza ve aramanıza olanak tanır. Anahtar benzersiz olmalıdır. Örneğin, CHashMap, numaranın anahtar olarak kullanıldığı belirli bir numaraya sahip bir siparişi anında bulabilir.
Anahtarla değer alma hakkında soru. Kütüphane kodunda, bu yöntem şöyle görünür
//+------------------------------------------------------------------+//| Find index of entry with specified key. |//+------------------------------------------------------------------+template < typename TKey, typename TValue>
int CHashMap::FindEntry(TKey key)
{
if (m_capacity!= NULL )
{
//--- get hash code from keyint hash_code=m_comparer.HashCode(key)& 0x7FFFFFFF ;
//--- search pair with specified keyfor ( int i=m_buckets[hash_code%m_capacity]; i>= 0 ; i=m_entries[i].next)if (m_entries[i].hash_code==hash_code && m_comparer.Equals(m_entries[i].key,key))
return (i);
}
return (- 1 );
}
Kaynaktaki ME gezinme araçları (ALT+G ve CTRL+-) bu kitaplıkta çalışmayı reddediyor. Bu nedenle, mantığı takip etmek çok zordur. Özellikle seçilen çevrimdeki başlangıç değerini henüz öğrenemedim. Ancak bir hız varsa, bu değerin anahtar sayısından çok daha az olması gerektiği konusunda bir anlayış var.
Lütfen bu fonksiyonda hangi hıza ulaşıldığı fikrini açıklayın? Taşma açıkça mevcut. Ama görünüşe göre nedense kısa.
Tehdit Bir hata ayıklayıcı ile adım adım yürüdüm. TKey = int: m_bucket[Array[i]] = i örneğinde her şey netleşti. Yalnızca Array[i] == Array[j] (i != j) olduğunda çarpışmalarla ilgilenilmez.
Anahtarla değer alma hakkında soru. Kütüphane kodunda, bu yöntem şöyle görünür Lütfen bu fonksiyonda hangi hıza ulaşıldığı fikrini açıklayın? Taşma açıkça mevcut. Ama görünüşe göre nedense kısa.
Bir keresinde CHashMap'in çalışma prensibini analiz ettim ve açıkladım. Büyük olasılıkla bu konudaki kayıtları aramanız gerekir.
template<typename TKey,typename TValue>
class CHashMap: public IMap<TKey,TValue>
{
protected :
int m_buckets[];
Entry<TKey,TValue>m_entries[];
int m_count;
int m_free_list;
int m_free_count;
IEqualityComparer<TKey>*m_comparer;
bool m_delete_comparer;
.................................
.................................
}
Öncelikle Entry<TKey,TValue>' nin ne olduğunu anlamanız gerekir. Aslında, bu, aşağıdakileri içeren CLinkedList'teki gibi bir Düğümdür:
- bir anahtar ve değer kabına yerleştirilir - anahtar için önbelleğe alınmış karma değer - hash_code - sonraki - çarpışmaları tek başına bağlantılı bir liste yoluyla çözmek için bir sonraki <TKey,TValue> Girişine "işaretçi"
m_entries[] - eklenen anahtar ve değerin, hash_code'un sonraki yerleştirildiği bir "hücre" dizisi. Dizinin boyutu Kapasiteye karşılık gelir. m_count - m_entries içindeki ilk kullanılmayan hücrenin dizinini gösterir. Başlangıç değeri 0'dır, Kapasite'ye kadar büyür, ardından tüm diziler Kapasite ve tüm dizilerin boyutunda bir artışla yeniden oluşturulur. m_buckets[] - m_entries[] üzerindeki dizin dizisi. Varsayılan değer -1'dir. Dizinin boyutu Kapasiteye karşılık gelir.
Çarpışma yok, CHashMap kapsayıcısına benzersiz bir değer ekliyor:
Anahtarla hash'i hesaplıyoruz, hash_code alıyoruz
Anahtar, değer, hash_code değerlerini m_count dizininde m_entries[] içine yerleştiriyoruz. (sonraki = -1 çünkü örnekte çarpışma yok)
m_buckets[] dizinine hash_code % (ArraySize(m_buckets)) dizinine yeni eklenen öğenin m_entries[] dizin değerini koyduk (bu m_count'tur).
m_count değerini +1 artırıyoruz
Çarpışma yok, CHashMap kapsayıcısında anahtara göre değer alıyor:
Anahtarla hash'i hesaplıyoruz, hash_code alıyoruz
m_buckets[] dizininden hash_code % (ArraySize(m_buckets)) dizininden m_entries[] dizisinden bir dizin olan bir değer alırız
Elde edilen indeks m_buckets[hash_code % (ArraySize(m_buckets))] tarafından m_entries[] dizisinden değer değerimizi alırız.
Çarpışma çözünürlüğü:
Farklı anahtarlar için hash_code_key_1 % (ArraySize(m_buckets)), hash_code_key_2 % (ArraySize(m_buckets)) değerine eşit olacaktır. Buna çarpışma denir. Bir çarpışma ile m_entries[] öğesine eklenen tüm öğeler, next aracılığıyla tek başına bağlantılı bir listeyle birbirine bağlanır (bkz. Entry<TKey,TValue> yapısı) Ve m_buckets[] her zaman bu çarpışma listesindeki ilk head öğesinin dizinine işaret eder. Çarpışmalı büyük bir liste değil, birçok küçük liste ortaya çıkıyor.
Çarpışma, CHashMap kapsayıcısında anahtara göre değer alma:
Anahtarla hash'i hesaplıyoruz, hash_code alıyoruz
m_buckets[] dizininden hash_code % (ArraySize(m_buckets)) dizininden m_entries[] dizisinden bir dizin olan bir değer alırız
Bir sonraki değerin -1'e eşit olmadığını görüyoruz, bu da bir çarpışmanın varlığını gösterir.
Tek tek bağlantılı bir m_entries[] öğeleri listesinden geçiyoruz ve eşitlik için istenen değeri kaydedilmiş anahtarlarla karşılaştırıyoruz
Bir CHashMap kapsayıcısından bir değeri kaldırma:
- m_entries[] içindeki bir hücreyi silerken hiçbir silme gerçekleşmez, hücre serbest olarak belirtilir ve hash_code = -1 olur. - serbest hücreler kendi serbest hücre listelerini oluştururlar (Entry<TKey,TValue>'den sonraki ile aynı), m_free_list liste baş indeksinden sorumludur - Container'a yeni değerler eklendiğinde ilk olarak serbest hücreler kullanılır. - m_free_count , mevcut boş hücre sayısını kontrol etmek için kullanılır
Hash tablosunu yeniden oluşturma (Kapasite artırma süreci):
- yeniden oluşturma yalnızca Kapasite %100 dolu olduğunda gerçekleşir. - aşağıdaki Kapasite listeden alınmıştır:
- m_entries[] ve m_buckets[] dizilerinin boyutları artar. - m_buckets[] temizlenir ve m_entries[]'den alınan verilere göre tamamen yeniden doldurulur (anahtar - hash_code için önbelleğe alınmış karma değer)
2017.12.11 itibariyle tanımlanan davranış Şu anda bazı detaylar/katsayılar eklenebilir/değiştirilebilir.
Bu örnekte, karma öğrencinin doğum günüdür. Öğrenci günlüklerini içeren 365 raflı bir dolabımız var. Her günlüğü, öğrencinin doğum gününe karşılık gelen bir rafa koyarız.
Petrov'un bir öğrencisinin günlüğüne ihtiyacımız var ve ne zaman doğduğunu biliyoruz. Şimdi, doğum gününe göre, O(1)'de Petrov'un günlüğünü kolayca bulabiliriz, tıpkı diğer öğrencilerin günlüğü gibi. İstisna, iki öğrencinin aynı doğum gününe sahip olmasıdır - buna çarpışma denir.
Çarpışma çözümü, iki veya daha fazla günlükten hangisine ihtiyacımız olduğunu belirlemek için ek bilgilerin kullanılmasıdır. Bir liste aracılığıyla çözümleme, bir çarpışmaya katılan tüm öğelerin istenen öğeyle eşleşmesi için basit bir sıralı numaralandırmadır. Her günlüğü yırtın ve kimin olduğunu görün. Alt karma sıralama, çarpışmaya dahil olan öğelerin bir karma tablosunun farklı bir kritere göre düzenlenmesidir. Örneğin, öğrenci doğduğunda.
Konuyla ilgileniyorsanız, youtube'daki MailRu'dan algoritmalar ve veri yapıları hakkında kursu tavsiye ederim.
MQL5.com web sitesine giriş yapmak için çerezlerin kullanımına izin vermelisiniz.
Lütfen tarayıcınızda gerekli ayarı etkinleştirin, aksi takdirde giriş yapamazsınız.
Hesabınıza giriş yaptınız. İki faktörlü kimlik doğrulama devre dışı bırakıldı. Yeniden kurup yeni bir QR kodu tarayın veya iki faktörlü kimlik doğrulama devre dışıyken devam edin.
İşlev, küresel düzeyde bildirilir. Bu nedenle, Karşılaştır kullanıcılarıyla bir çakışma var.
Adlandırma çakışmalarını azaltmak için Yazar, tüm genel Genel yardımcı işlevleri genel statik yöntemler yapabilir mi?
fxsaber :
Adlandırma çakışmalarını azaltmak için Yazar, tüm genel Genel yardımcı işlevleri genel statik yöntemler yapabilir mi?
Ticaret, otomatik ticaret sistemleri ve ticaret stratejilerinin test edilmesi hakkında forum
Derleyici hatası: 'operator=' - yapıda nesneler var ve kopyalanamaz
Bu şu an için. Her şey bir araya toplandığında, çöküş kaçınılmazdır) Birinin kitaplığını dahil etmek istiyorsanız, o zaman yazarın sizin yaptığınız gibi aynı "ilkel" şekilde, aynı sınıf ve işlev adlarını kullanarak yazdığı ortaya çıkar.
Seni makrolarla yeneceğim, seni makrolarla yeneceğim.
Kendinden bahsetmiyordu.
Tartışmanın tüm sayfalarını okudum ama nasıl kullanılacağını anlamadım?
Herkes örnek verebilir mi?
Tartışmanın tüm sayfalarını okudum ama nasıl kullanılacağını anlamadım?
Herkes örnek verebilir mi?
Öldür onu. Şimdiki haliyle kullanılamaz. Bunun yerine, standart CObject + CDictionary'yi kullanın . Çoğu görev için bu yeterlidir.
Anahtarla değer alma hakkında soru. Kütüphane kodunda, bu yöntem şöyle görünür
Kaynaktaki ME gezinme araçları (ALT+G ve CTRL+-) bu kitaplıkta çalışmayı reddediyor. Bu nedenle, mantığı takip etmek çok zordur. Özellikle seçilen çevrimdeki başlangıç değerini henüz öğrenemedim. Ancak bir hız varsa, bu değerin anahtar sayısından çok daha az olması gerektiği konusunda bir anlayış var.
Lütfen bu fonksiyonda hangi hıza ulaşıldığı fikrini açıklayın? Taşma açıkça mevcut. Ama görünüşe göre nedense kısa.
Tehdit Bir hata ayıklayıcı ile adım adım yürüdüm. TKey = int: m_bucket[Array[i]] = i örneğinde her şey netleşti. Yalnızca Array[i] == Array[j] (i != j) olduğunda çarpışmalarla ilgilenilmez.
Anahtarla değer alma hakkında soru. Kütüphane kodunda, bu yöntem şöyle görünür
Lütfen bu fonksiyonda hangi hıza ulaşıldığı fikrini açıklayın? Taşma açıkça mevcut. Ama görünüşe göre nedense kısa.
Bir keresinde CHashMap'in çalışma prensibini analiz ettim ve açıkladım.
Büyük olasılıkla bu konudaki kayıtları aramanız gerekir.
Ticaret, otomatik ticaret sistemleri ve ticaret stratejilerinin test edilmesi hakkında forum
Genel sınıf kitaplığı - hatalar, açıklama, sorular, kullanım ve öneriler
Sergey Dzyublik , 2017.12.11 13:41
CHashMap'in mevcut uygulaması hakkında kısaca:
Öncelikle Entry<TKey,TValue>' nin ne olduğunu anlamanız gerekir.
Aslında, bu, aşağıdakileri içeren CLinkedList'teki gibi bir Düğümdür:
m_entries[] - eklenen anahtar ve değerin, hash_code'un sonraki yerleştirildiği bir "hücre" dizisi. Dizinin boyutu Kapasiteye karşılık gelir.
m_count - m_entries içindeki ilk kullanılmayan hücrenin dizinini gösterir. Başlangıç değeri 0'dır, Kapasite'ye kadar büyür, ardından tüm diziler Kapasite ve tüm dizilerin boyutunda bir artışla yeniden oluşturulur.
m_buckets[] - m_entries[] üzerindeki dizin dizisi. Varsayılan değer -1'dir. Dizinin boyutu Kapasiteye karşılık gelir.
Çarpışma yok, CHashMap kapsayıcısına benzersiz bir değer ekliyor:
Çarpışma yok, CHashMap kapsayıcısında anahtara göre değer alıyor:
Çarpışma çözünürlüğü:
Çarpışma, CHashMap kapsayıcısında anahtara göre değer alma:
Bir CHashMap kapsayıcısından bir değeri kaldırma:
Hash tablosunu yeniden oluşturma (Kapasite artırma süreci):
2017.12.11 itibariyle tanımlanan davranış
Şu anda bazı detaylar/katsayılar eklenebilir/değiştirilebilir.
Bir keresinde CHashMap'in çalışma prensibini analiz ettim ve açıkladım.
Büyük olasılıkla bu konudaki kayıtları aramanız gerekir.
Bulundu
Ticaret, otomatik ticaret sistemleri ve ticaret stratejilerinin test edilmesi hakkında forum
Genel sınıf kitaplığı - hatalar, açıklama, sorular, kullanım ve öneriler
Sergey Dzyublik , 2017.12.07 14:21
Bu örnekte, karma öğrencinin doğum günüdür.
Öğrenci günlüklerini içeren 365 raflı bir dolabımız var.
Her günlüğü, öğrencinin doğum gününe karşılık gelen bir rafa koyarız.
Petrov'un bir öğrencisinin günlüğüne ihtiyacımız var ve ne zaman doğduğunu biliyoruz.
Şimdi, doğum gününe göre, O(1)'de Petrov'un günlüğünü kolayca bulabiliriz, tıpkı diğer öğrencilerin günlüğü gibi.
İstisna, iki öğrencinin aynı doğum gününe sahip olmasıdır - buna çarpışma denir.
Çarpışma çözümü, iki veya daha fazla günlükten hangisine ihtiyacımız olduğunu belirlemek için ek bilgilerin kullanılmasıdır.
Bir liste aracılığıyla çözümleme, bir çarpışmaya katılan tüm öğelerin istenen öğeyle eşleşmesi için basit bir sıralı numaralandırmadır. Her günlüğü yırtın ve kimin olduğunu görün.
Alt karma sıralama, çarpışmaya dahil olan öğelerin bir karma tablosunun farklı bir kritere göre düzenlenmesidir. Örneğin, öğrenci doğduğunda.
Konuyla ilgileniyorsanız, youtube'daki MailRu'dan algoritmalar ve veri yapıları hakkında kursu tavsiye ederim.
Ticaret, otomatik ticaret sistemleri ve ticaret stratejilerinin test edilmesi hakkında forum
Genel sınıf kitaplığı - hatalar, açıklama, sorular, kullanım ve öneriler
Sergey Dzyublik , 2017.12.08 14:40
Tembel için konuyla ilgili temel bilgiler:
https://www.slideshare.net/mkurnosov/6-32402313
Gerçekte, her şey çok daha karmaşıktır ve ilgili literatürde veya iyi "algoritmalar ve veri yapıları" derslerinde tartışılmaktadır.
Teşekkürler, hata ayıklama yardımcı oldu. Çarpışmalar için küçük listeler var. Dal boyunca koştum ve dehşete düştüm. İçinde olduğu ortaya çıktı...
Şu anda bazı detaylar/katsayılar eklenebilir/değiştirilebilir.
Çok teşekkürler! Açıklamamda bana çok yardımcı oldular.