기고글 토론 "MQL5 Cookbook: 빠른 데이터 액세스를 위한 연관 배열 또는 사전 구현" - 페이지 4

 
Vasiliy Sokolov:

여기에는 몇 가지 이유가 있을 수 있습니다. 대부분 유형 비호환성 또는 포인터의 잘못된 처리일 가능성이 높습니다. 또한 템플릿 메서드 작업의 특성을 배제할 수 없습니다(여기에도 고유한 뉘앙스가 있습니다).

일반적으로 기성 거래 엔진을 사용하는 것이 더 좋으며 많은 시간과 신경을 절약 할 수 있습니다 : https://www.mql5.com/ko/articles/2166.

안녕하세요! 전체 사전을 반복하여 특정 조건으로 쌍을 제거하는 방법을 알려 주실 수 있습니까? 다음은 그러한 작업의 예입니다.

#include <Dictionary.mqh>

class CInt : public CObject
  {
public:
   int               value;
                     CInt(int _value = 0) : value(_value) {}
  };
  
CDictionary d;
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
int OnInit()
  {
   d.FreeMode(true);
   for(int i = 0; i < 10; ++i)
     {
      CInt *int_value = new CInt(i);
      d.AddObject(i, int_value);
     }
   for(CInt *node = d.GetFirstNode(); node != NULL;)
     {
      if(node.value % 2 == 0)
         // d.DeleteCurrentNode() 또는 d.DeleteObjectByKey(node.value);
         
      // 사전을 반복하는 방법???? 
     }
     
   return(INIT_SUCCEEDED);
  }
 
vek_y4icb:

안녕하세요! 전체 사전을 반복하여 특정 조건으로 쌍을 제거하는 방법을 알려주실 수 있나요? 다음은 그러한 작업의 예입니다.

좋은 질문입니다. 이제 귀하의 방법을 사용하여 삭제를 확인했지만 제대로 작동하지 않습니다. 나는 그것을 조사 할 것입니다.

 
Vasiliy Sokolov:

좋은 질문입니다. 지금 귀하의 방법을 사용하여 삭제를 확인했지만 제대로 작동하지 않습니다. 제가 살펴보겠습니다.

일반적인 경우에는 제대로 작동하지 않을 것입니다.

연관 배열에서 여러 개의 삭제를 수행하는 올바른 방법은 삭제할 키 배열을 수집한 다음 키별로 삭제하는 것입니다.

 
Andrei Trukhanovich:

일반적으로 올바르게 작동할 필요는 없습니다.

연관 배열에서 여러 개의 삭제를 수행하는 올바른 방법은 삭제할 키 배열을 수집한 다음 키별로 삭제하는 것입니다.

이것은 이해할 수 있지만 다시 말하지만 불필요한 작업입니다.

 
Vasiliy Sokolov:

좋은 질문입니다. 지금 귀하의 방법을 사용하여 삭제를 확인했지만 제대로 작동하지 않습니다. 제가 살펴보겠습니다.

답변해 주셔서 감사합니다!

 
Andrei Trukhanovich:

일반적으로 올바르게 작동할 필요는 없습니다.

연관 배열에서 여러 개의 삭제를 수행하는 올바른 방법은 삭제할 키 배열을 수집한 다음 키별로 삭제하는 것입니다.

그런데 이 방법도 갑자기 이상한 버그가 발생합니다. 분명히 오류입니다. 조사해 보겠습니다.

지금은 새 사전을 만들고 삭제할 필요가없는 값을 추가하도록 조언 할 수 있습니다. 그런 다음 이전 사전을 지우십시오. 이것은 100 % 작동합니다.

 

방법은 다음과 같습니다:

1. 사전 버전을 이 게시물에 첨부된 버전으로 업데이트합니다.

2. 테스트 스크립트를 실행하여 요소를 삭제합니다.

삭제는 두 번에 걸쳐 수행해야 합니다:

int OnStart()
  {
   d.FreeMode(true);
   for(int i = 0; i < 10; ++i)
   {
      CInt *int_value = new CInt(i);
      d.AddObject(i, int_value);
   }
   //-- 삭제할 키 목록 만들기
   CArrayInt delKeys;
   for(CInt *node = d.GetFirstNode(); node != NULL; node = d.GetNextNode())
   {
      if(node.value % 2 == 0)
         delKeys.Add(node.value);
   }
   //-- 삭제하도록 할당된 개체를 각각 개별적으로 삭제합니다.
   for(int i = 0; i < delKeys.Total(); i++)
      d.DeleteObjectByKey(delKeys.At(i));
   for(CInt *node = d.GetFirstNode(); node != NULL; node = d.GetNextNode())
   {
      printf(node.value);
   }
     
   return(INIT_SUCCEEDED);
  }

DeleteCurrentObject() 메서드에 대해 설명합니다:

이 메서드는 ContainsKey() 함수와 함께 사용해야 합니다. 이 메서드를 공개로 사용할 수 있는 유일한 이유는 이 경우 메서드를 호출하면 포인터를 재배치하는 데 드는 시간을 절약할 수 있기 때문입니다. 즉, 이 함수를 사용하는 일반적이고 유일한 경우는 1입니다. 키가 있는지 확인하고, 키가 있으면 이 메서드를 사용하여 빠르게 삭제하는 경우입니다.

파일:
 
vek_y4icb:

이해할 수 있지만 다시 말하지만 불필요한 차체입니다.

기술적으로 예상대로 원패스 제거가 가능합니다. 하지만 복잡할 것입니다. 그렇기 때문에 아직은 두 번의 패스로만 가능합니다. 분산 데이터 구조로서의 사전의 관점에서 볼 때, 2패스 삭제가 더 정식으로 올바른 해결책입니다. 사용자 수준에서만 삭제가 순차적으로 이루어지는 것처럼 보이지만 실제로는 모든 것이 다릅니다. 성능 측면에서 단일 패스 삭제는 아무런 이점을 제공하지 않습니다. 편의성 측면에서는 예, 더 편리할 수 있습니다.

 
Vasiliy Sokolov:

기술적으로 예상대로 원패스 제거를 수행하는 것은 가능합니다. 하지만 복잡할 것입니다. 그렇기 때문에 아직은 두 번의 패스로만 가능합니다. 분산 데이터 구조로서의 사전의 관점에서 볼 때 2패스 삭제가 더 표준적으로 정확합니다. 사용자 수준에서만 삭제가 순차적으로 이루어지는 것처럼 보이지만 실제로는 모든 것이 다릅니다. 성능 측면에서 단일 패스 삭제는 아무런 이점을 제공하지 않습니다. 편의성 측면에서는 예, 더 편리할 수 있습니다.

고마워요.

[삭제]  
Marcel Fitzner:

요소를 삭제하고 마지막 요소로 이동하려고 할 때 버그를 발견한 것 같습니다:

CDictionary.mqh에서 오류가 발생합니다:

'Dictionary.mqh'에서잘못된 포인터 액세스 (463,9)

누구든지 이것을 확인할 수 있습니까? 어떻게 고칠 수 있을까요?



포인터를 확인하는 구현에 대한 500 및 501 줄의 버그였습니다.

내장된 CheckPointer()를 사용하여 수정했습니다.

파일:
CDictionary.mqh  21 kb