記事"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


初心者の方には必見の記事です。

削除済み  
ありがとう。
 
いい記事だ。
 

私たちが無知でなくなるように、あなたを疲れさせるのはいいことだ。

 

文字列に桁グループの区切り文字を追加する:

//+------------------------------------------------------------------+
//|DelimiterGroupsDigits.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