汎用クラスライブラリ - バグ、説明、質問、使用上の特徴、提案 - ページ 22

 
アレクセイ・ナヴォイコフ

どうやら継承という意味ではなく、構造体の上にクラスからラッパーをかぶせたということでしょうか?

の右側です。
 
//+------------------------------------------------------------------+
//| Determines whether a set contains the specified element.         |
//+------------------------------------------------------------------+
template<typename T>
bool CHashSet::Contains(T item)
  {
//--- check buckets
   if(ArraySize(m_buckets)!=0)
     {
      //--- get hash code for item      
      int hash_code=m_comparer.HashCode(item)&0x7FFFFFFF;
      //--- search item in the slots       
      for(int i=m_buckets[hash_code%ArraySize(m_buckets)]-1; i>=0; i=m_slots[i].next)
         if(m_slots[i].hash_code==hash_code && m_comparer.Equals(m_slots[i].value,item))
            return(true);
     }
   return(false);
  }

なぜ符号のビットが切れているのですか?

 
fxsaber

なぜ符号のビットが切れているのですか?

ハッシュは配列のインデックスとして働くので,正数でなければなりません。

 
TheXpert です。

ハッシュは配列のインデックスとして働くので,正数でなければなりません。

uint?

 
fxsaber

uint?

意味がない

Документация по MQL5: Операции с массивами / ArraySize
Документация по MQL5: Операции с массивами / ArraySize
  • www.mql5.com
"Нулевое измерение = Размер массива / (Первое измерение * Второе измерение * Третье измерение)"
 
TheXpert です。

意味がない

ハイライトされた行の組み合わせがおかしい

トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム

汎用クラスライブラリ - バグ、説明、問題、使用例、提案

fxsaber さん 2018.06.11 20:04

//+------------------------------------------------------------------+
//| Determines whether a set contains the specified element.         |
//+------------------------------------------------------------------+
template<typename T>
bool CHashSet::Contains(T item)
  {
//--- check buckets
   if(ArraySize(m_buckets)!=0)
     {
      //--- get hash code for item      
      int hash_code=m_comparer.HashCode(item)&0x7FFFFFFF;
      //--- search item in the slots       
      for(int i=m_buckets[hash_code%ArraySize(m_buckets)]-1; i>=0; i=m_slots[i].next)
         if(m_slots[i].hash_code==hash_code && m_comparer.Equals(m_slots[i].value,item))
            return(true);
     }
   return(false);
  }

トリミングしたハッシュとカットしていないハッシュの比較は?

 
fxsaber

トリミングしたハッシュとカットしていないハッシュの比較は?

どれも切り捨てられていると思うのですが、最初に言っておきますが、私はコードをざっと見ただけで、しかもかなり前に見たので、間違っている可能性があります。

項目を追加するコードを見てください。

 
TheXpert です。

全部トリミングされていると思うのですが、はっきり言って、ずいぶん前にコードをチラッと見ただけなので、間違っているかもしれませんね。

項目を追加するコードを見てください。

//+------------------------------------------------------------------+
//| Insert the value with the specified key from the map.            |
//+------------------------------------------------------------------+
template<typename TKey,typename TValue>
bool CHashMap::Insert(TKey key,TValue value,const bool add)
  {
   if(m_capacity==0)
      Initialize(0);
//--- get hash code from key
   int hash_code=m_comparer.HashCode(key)&0x7FFFFFFF;
   int target_bucket=hash_code%m_capacity;
//--- collisions count in one bucket with different hashes
   int collision_count=0;
//--- search pair with specified key
   for(int i=m_buckets[target_bucket]; i>=0; i=m_entries[i].next)
     {
      //--- hash compare      
      if(m_entries[i].hash_code!=hash_code)
        {
         collision_count++;
         continue;
        }
      //--- value compare     
      if(m_comparer.Equals(m_entries[i].key,key))
        {
         //--- adding duplicate
         if(add)
            return(false);
         m_entries[i].value=value;
         return(true);
        }
     }
//--- check collision
   if(collision_count>=m_collision_threshold)
     {
      int new_size=CPrimeGenerator::ExpandPrime(m_count);
      Resize(new_size);
     }
//--- calculate index
   int index;
   if(m_free_count>0)
     {
      index=m_free_list;
      m_free_list=m_entries[index].next;
      m_free_count--;
     }
   else
     {
      if(m_count==ArraySize(m_entries))
        {
         int new_size=CPrimeGenerator::ExpandPrime(m_count);
         Resize(new_size);
         target_bucket=hash_code%new_size;
        }
      index=m_count;
      m_count++;
     }
//--- set pair
   m_entries[index].hash_code=hash_code;
   m_entries[index].next=m_buckets[target_bucket];
   m_entries[index].key=key;
   m_entries[index].value=value;
   m_buckets[target_bucket]=index;
   return(true);
  }

はい、ありがとうございます。ただ、コードでトリミングされていないものはないんです。HashCodeメソッド自体でトリミングをしないのは変ですね。どうやらフールプルーフ(曲がったカスタムハッシュ)のための計算だったようです。

 

既出だったらごめんなさい。ドキュメントに記載がなかった。

Set-upsのループはありますか? iteratorはありますか?

 
ヴィクトル・ルビモフ

既出だったらごめんなさい。ドキュメントに記載がなかった。

セットアップのループはありますか?

残念ながら、そうではありません。
でも、自分で実装することは可能です。
例えば、MQL5 RECEIPTS - REALIZE ASSOCIATED MASSIVE OR WORLD DATABASE FOR FAST DATA ACCESSの 記事中の例をご覧ください。

void ReverseEnumerateAll(CList& list)
{
   CObject* node = list.GetLastNode();
   for(int i = list.Total()-1; node != NULL; i--, node = node.Prev())
      printf("Element at " + (string)i); 
}
Как работает этот код? На самом деле все просто. В функции EnumerateAll() в самом начале мы получаем ссылку на первый узел. Затем в цикле for мы печатаем порядковый узел этого узла 
и переходим к следующему узлу командой node = node.Next(), не забывая при этом проитерировать текущий индекс элемента на единицу (i++). Перебор продолжается до тех пор, пока текущий 
узел node не станет равен NULL, за это ответствен код во втором блоке for: node != NULL.

Аналогично работает реверсивная версия этой функции ReverseEnumerateAll() с той лишь разницей, что она вначале получает последний элемент списка CObject* node = list.GetLastNode(). 
В цикле for она получает не следующий, а предыдущий элемент списка node = node.Prev().