기고글 토론 "MQL5 프로그래밍 기본: 문자열" - 페이지 2

 
denkir:

...개인적으로 회선 길이 제한에 대한 질문이 궁금했습니다....

지금 실험 해보니 32MB가 맞고 더 많이 맞을 수 있지만 시간이 오래 걸립니다.
 

According to the description of these functions in MQL5 Reference, they allow us to add up strings in a more space efficient (in terms of the occupied working memory) and faster way.

사실 문서에 일관성이 없습니다. 메모리 사용량에 대해서는 모르겠지만 더 빠르거나 그렇지 않은지에 대해서는 StringConcatenate ()가 StringAdd 및 +보다 훨씬 느립니다.

2013.04.11 19:09:48    teststring (EURUSD,M1)    time for 'StringConcatenate(c,a,b)' = 1170 milliseconds, i = 1000000
2013.04.11 19:09:47    teststring (EURUSD,M1)    time for 'StringAdd(a,b)' = 94 milliseconds, i = 1000000
2013.04.11 19:09:47    teststring (EURUSD,M1)    time for 'c = a + b' = 265 milliseconds, i = 1000000


좋은 기사, 모든 초보자를위한 필수품.

[삭제]  
감사합니다.
 
좋은 기사입니다, 감사합니다.
 

우리를 덜 무지하게 만들기 위해 당신을 지치게하는 것이 좋습니다. 당신의 일에 감사드립니다.

 

문자열에 숫자 그룹 구분 기호를 추가합니다:

//+------------------------------------------------------------------+
//|구분 기호 그룹 숫자.mq5 |
//| Copyright 2018, MetaQuotes Software Corp.
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property script_show_inputs
//--- 외부 매개변수
input double Value     =1000000;
input string Delimiter =" "; // 구분 기호, 기본값: " ", 예: 1 000 000.0
//+------------------------------------------------------------------+
//| 스크립트 프로그램 시작 기능|
//+------------------------------------------------------------------+
void OnStart(void)
  {
   ::Print(DelimiterGroupsDigits(string(Value),Delimiter));
  }
//+------------------------------------------------------------------+
//| 숫자 그룹 구분 기호|
//+------------------------------------------------------------------+
string DelimiterGroupsDigits(const string value,const string delimiter=" ")
  {
   string res=value;
   string elements[];
//--- 가장자리에서 여분의 문자를 제거합니다.
   ::StringTrimLeft(res);
   ::StringTrimRight(res);
//--- 실수 확인
   ushort sep   =::StringGetCharacter(".",0);
   int    total =::StringSplit(res,sep,elements);
//--- 문자열을 가져왔습니다.
   if(total>0)
     {
      string str[];
      int length=::StringLen(elements[0]);
      for(int k=0,i=length-1; i>=0; i--)
        {
         int size=::ArraySize(str);
         ::ArrayResize(str,size+1);
         str[size]=::StringSubstr(elements[0],i,1);
         k++;
         //--- 구분 기호 추가
         if(k>=3 && i>0)
           {
            int array_size=::ArraySize(str);
            ::ArrayResize(str,array_size+1);
            str[array_size]=delimiter;
            k=0;
           }
        }
      //--- 문자열 수집
      res="";
      int elements_total=::ArraySize(str);
      for(int i=elements_total-1; i>=0; i--)
         ::StringAdd(res,str[i]);
      //--- 실수인 경우
      if(total>1)
         ::StringAdd(res,"."+elements[1]);
     }
//--- 결과 반환
   return(res);
  }
//+------------------------------------------------------------------+

//---

결과:

1 000 000.0
10,000,000.0
100'000'000.0
10 000.545
 
Anatoli Kazharski:

문자열에 숫자 그룹 구분 기호를 추가합니다:

다소 복잡합니다.
 
fxsaber:
좀 복잡하네요.
최적화를 시도해 보시겠어요?
 
Anatoli Kazharski:
최적화를 시도해 보시겠습니까?
string ModToString( ulong &Num, const int Mod = 1000, const int Len = 3 )
{
  const string Res = ((bool)(Num / Mod) ? IntegerToString(Num % Mod, Len, '0') : (string)(Num % Mod));
  
  Num /= Mod;
  
  return(Res);
}

string NumToString( ulong Num, const string Delimeter = " " )
{
  string Res = ModToString(Num);

  while (Num)
    Res = ModToString(Num) + Delimeter + Res;

  return(Res);
}

string NumToString( double Num, const int digits = 8, const string Delimeter = NULL )
{
  const string PostFix = (Num < 0) ? "-" : NULL;
  
  Num = MathAbs(Num);
    
  return(PostFix + NumToString((ulong)Num, Delimeter) + StringSubstr(DoubleToString(Num - (long)Num, digits), 1));
}

void OnStart()
{
  Print(NumToString(1234567.89, 2, " "));
}
 
fxsaber:

대단하네요! 그리고 4배 더 빠릅니다:

void OnStart(void)
  {
   long count=10000000;
   uint start=GetTickCount();
   for(int i=0; i<count && !IsStopped(); i++)
      DelimiterGroupsDigits(string(Value),Delimiter);

   uint end=GetTickCount()-start;
   Print("01 > ms: ",end,"; res: ",DelimiterGroupsDigits(string(Value),Delimiter));
//---
   start=GetTickCount();
   for(int i=0; i<count && !IsStopped(); i++)
      NumToString(Value,2,Delimiter);

   end=GetTickCount()-start;
   Print("02 > ms: ",end,"; res: ",NumToString(Value,2,Delimiter));
  }

//---

2018.01.30 21:02:15.996 01 > ms: 19047; res: 1 000 000.0
2018.01.30 21:02:20.683 02 > ms: 4688; res: 1 000 000.00