MQL4、MQL5に関する初心者からの質問、アルゴリズムやコードに関するヘルプ、ディスカッションなど。 - ページ 1413

 
Alexey Viktorov:

IntegerToString() および DoubleToString() 関数は、単に数値を文字列として表現し、関数に渡します。例では

は、rを文字列に変換して、文字列を「足し算」しているのです。しかし、その前にrの値が変化してしまうのです。

質問の意味がよくわからないのですが、配列から偶数番目の要素だけを選択する必要がある場合、ループは次のように構築する必要があります。


説明ありがとうございました。

 
Alexey Viktorov:

IntegerToString() および DoubleToString() 関数は、単に数値を文字列として表現し、関数に渡します。例では

は、rを文字列に変換して、文字列を「足し算」しているのです。しかし、その前にrの値が変化してしまう。



文字列変数の値を「追加」する処理が理解できない。私のコードでは、「追加」文字列の2つのバリエーションが見られます。

1.これは、現在の反復処理の文字列変数の値と、前の反復処理の同じ文字列変数の値を足し合わせたものである。

2.現在の反復処理では、2つの項変数の値が加算される。すなわち、IntegerToString(r)+ DoubleToString(LoY[r],4) である。

最初のバリエーションを意味しているようです。

と思いきや.前の繰り返しにおけるIntegerToString(r)の値= "0"であり、現在のイテレーションでは = "1" .加算結果は "01 "になるはずです。

もし、現在の反復計算で、合計する前にIntegerToString(r) の 値が以前の 0 から現在の 1 に変わったとしても、2桁の文字列表現、つまり "11" を得ることができます。

同じアルゴリズムで文字列変数DoubleToString(LoY[r],4) の値を加算すると、2つの文字列の加算結果は 1.61041.6105 のような値になるはず です。

しかし、Print()は加算結果をなぜか他の数値で表示する(はず)
よくわからない。
文字列変数の値が合計される例です。「......文字列を 合計するとDoubleToString(2.3, 1)+.DoubleToString(3.6, 1)とすると、文字列としては2.33.6となる。"つまり、加算前は各変数の数値を表す文字列は2文字だったが、2つの文字列変数を加算した結果、4文字の数値を表す文字列となったのである。あなたのコードで足し算をすると、なぜ2倍の文字数の数字にならないのでしょうか?

 
Alexey Viktorov:


質問の意味がよく わからないのですが、配列から偶数番目の要素だけを選択したい場合は、次のようなループを組む必要があります。


実は、こういうことなんです...。以下は、BOX2で完成したオリジナルコードです。

int P1=0;
double LoY[31];
void OnTick()
{
if (P1==0)
{
for(int r=0; r<31;r++)
{
LoY[r]=1.6104+(r*2)*0.0001;
Print("-------------------------------------LoY[r]--------------=",  LoY[r]);
P1=1;
}
}
//*************************************************************  Б Л О К    N 2
for(int x=0; x<31;x++)
{
if (Bid < LoY[x] )
{
LoY[x]=Bid;
ArraySort(LoY,WHOLE_ARRAY,0,MODE_ASCEND);
Print("---LoY[0]--",  X, "---LoY[1]--" ,  X,   "---LoY[2]--" ,  X,  "---LoY[3]--" ,  X,  "---LoY[4]--" ,  X, ................  "---LoY[30]--" ,  X );
}
}
}

2番目のブロックでは、配列の要素の 値が1番目のブロックと同じデルタ数で違わなくなりました。 隣接する要素間のデルタは異なる場合があります ということで、1ブロック目の文字列をつなぐアルゴリズムは、2ブロック目には適さない......ということのようです。

質問 上記のコードの2番目の ブロックのどのMQL4言語コンストラクト または関数で、ループの終わりにあるPrint()関数は、配列要素のすべての値が記入され、1行に並んだ状態で1回だけ 印刷されます、つまり、次の形式になります。

Print("---LoY[0]--" , X,"---LoY[1]--",X,"---LoY[2]--"),X,"---LoY[3]--",X,"---LoY[4]--",X."---LoY[30]--",X );

厳しく判断しないでほしいのですが、2つ目のブロックは1つ目のブロックよりずっと複雑なので、言葉で説明してもよくわからない......ような気がします。
ご協力ありがとうございました。

 

プログラミングをする場合、少なくとも最初のうちはルーチンワークが多くなります。考え抜いて、コードを書いて、デバッグして。デバッグの時間が他の何よりも長くかかることがあります。

最初のアイデアがうまくいかないことはよくあることです。上から順番に悪いところを見ていくんです。

あらゆるところにprintf()を挿入して、これが期待通りのものかどうか見てみましょう。そうすることで、コードがどのように動くのか、どこでエラーになっているのかを素早く理解することができます。そうでないと、理解するのに時間がかかってしまいます。


余計なお世話ですが、美しく書くことを心がけてください。自分のスタイルを選び、それを貫く。アタッチメントが見えるように、段階的にブラケットを配置する。文と文の間にスペースを使うなら、どこでも使うし、逆にどこでも使わなくてもいい。

for(int x=0; x<31;x++)

if (Bid < LoY[x] )

そうすれば、自分のコードを読むのが楽になります。

-----------------

2ブロック目では

2番目のブロックでは、小文字のxと大文字のXは異なる変数であり、コードはあなたが望むように動作しません。

ループの外側で配列をソートするのがよいでしょう。

PrintではXを何回も使うと、同じ回数だけ印刷することになります。

-----------------

コードについては質問の意味がわかりにくいので、私が理解したことをお話しします。

ループの中でPrintを書くと、そのループが反復した数だけプリントアウトされます。もし、出力を一度だけ表示する必要がある場合は、ループの後にPrintを配置します。

この場合、各反復の値を書き込む変数を使用して、情報を収集する。私たちの変数は文字列なので、すべての数値を文字列に変換する必要があります。

Print関数が文字列を受け付けるので、文字列変数を用意しています。

何が起こっているのか

最初のパスループの前の最初のパスの前に、空の変数があります:string str="";
次に、変数に空の値を代入します プラス"--LoY["+IntegerToString(r)+"]--, "+DoubleToString(LoY[r],4)+",";
ここでは r は 0 で実際にいくつかのストリングを追加しています。

"--LoY["+

IntegerToString(0)+.

"]--, "+

DoubleToString(LoY[0],4)+.

", ";

2回目のパス

これに、2つ目の要素の情報を追加します。

"--LoY["+IntegerToString(1)+"]--, "+DoubleToString(LoY[1],4)+", ";

これは、最初の要素から文字列を変更しない。



どうやるかよりも、何が必要なのか、目的を言葉で説明したほうがいい。そうでないと、長々とコードを議論しているうちに、あなたの目的は別の方法で解決できることが分かってしまうかもしれません。

 
ANDREY:

文字列変数の値を「足し算」する処理が理解できない。私のコードでは、文字列を「追加」するための2つのオプションがあります。

1.現在の反復処理の文字列変数の値が、前の反復処理の同じ文字列変数の値に加算される。

2.現在の反復処理では、2つの項変数の値が加算される。すなわち、IntegerToString(r)+ DoubleToString(LoY[r],4) である。

最初のバリエーションを意味しているようです。

と思いきや.前の繰り返しにおけるIntegerToString(r)の値= "0"であり、現在のイテレーションでは = "1" .加算結果は "01 "になるはずです。

IntegerToString(r)の 値が加算前に以前の0から現在の1に変化しても、2桁の文字列表現、すなわち「11」を得ることができるのです。

文字列変数DoubleToString(LoY[r],4) の値を同じアルゴリズムで加算すると、2つの文字列の加算結果は1.61041.6105のようになるはず である。

しかし、Print()はなぜか足し算の結果を他の数値(のようなもの)として出力してしまう
よくわからない。
ここでは、文字列変数の値を追加する例として、「......」と文字列を 追加するとDoubleToString(2.3, 1)+.DoubleToString(3.6, 1)とすると、文字列としては2.33.6となる。"つまり、加算前は各変数の数を表す文字列は2文字だったが、2つの文字列変数を加算した結果、4文字の数を表す文字列になる。あなたのコードで足し算をすると、なぜ2倍の文字数の数字にならないのでしょうか?

実はこれ、どんな文章でも書くのと同じなんです。まずは白紙、いや、白線というべきか。そして、最初の単語を書き、2番目の単語をそれに付け加える......というように、文章中に数字が出てきたら、それを線記号で書くのです。つまり、2+5を足すと7になりますが、この同じ数字をそのまま書くと、まず2を書き、次に5を書く...というように、2つの数字25が隣り合わせで書かれていることになります。他にどう説明したらいいのかわからない。

実は、コンパイラの警告を無視すれば、サンプルでのr値の文字列への変換は必要ないのです。ここで、以下の2つのオプションを確認します。

Print("Test 1 " + (string)1 + (string)2);
Print("Test 2 " + 1 + 2);
 
Aleksei Stepanenko:


ご教授ありがとうございました。

 
Alexey Viktorov:

実は、どんな文章でも書くのと全く同じなのです。まず白紙というか、白線というべきものを用意します。そして、最初の単語を書き、それに2番目の単語を加えて......というように、文章中に数字が出てきたら、それを線記号で書くのです。つまり、2+5を足すと7になりますが、この同じ数字をそのまま書くと、まず2を書き、次に5を書く...というように、2つの数字25が隣り合わせで書かれていることになります。他にどう説明したらいいのかわからない。

実は、コンパイラの警告を無視すれば、サンプルでのr値の文字列への変換は必要ないのです。ここで、そんな2つのバリエーションを確認します。

いつもありがとうございます

 
ANDREY:

というのは、実はこういうことなんです...。以下は、BOX2によって補足されたオリジナルのコードです。

2番目のブロックでは、配列の要素の 値が1番目のブロックと同じデルタ数で異なっていません。 隣接する要素間のデルタが異なる場合がある ということで、1ブロック目の文字列をつなぐアルゴリズムは、2ブロック目には適さない......ということのようです。

質問 上記のコードの2番目の ブロックにあるどのMQL4言語の構成要素 または関数で、Print()関数はループ終了後に1回だけ、配列要素のすべての値を1行に詰めて印刷します。

Print("---LoY[0]--" , X,"---LoY[1]--",X,"---LoY[2]--"),X,"---LoY[3]--",X,"---LoY[4]--",X."---LoY[30]--",X );

厳しく判断しないでほしいのですが、2つ目のブロックは1つ目のブロックよりずっと複雑なので、言葉で説明してもよくわからない......ような気がします。
ありがとうございました。

また、なぜループの各反復で配列をソートするのでしょうか?なぜなら、配列の0番目の要素の値を入れ替えて、ソート後に配列の最後尾に行った場合、0は1番目だった値になり、1番目は2番目だった値になるからです。したがって、配列の最初の項目の値はスキップされ、"rubbish "を得ることになります。全体として、あなたのコードはすべて何かズレていますね。

アレイを埋めている最初のブロックは何のために必要ですか?必要な値ですぐに配列を埋めて、それからソートします。True の場合、文字列を埋めてプリントするために、もう1つループを実行する必要があります。mql4にArrayPrint()があればいいのですが...あくまで実験なので、実際に配列の値を表示する必要はないでしょう。

 
Aleksei Stepanenko:

どうやるかではなく、何が 必要か、目標を言葉で説明した方がいい。そうでないと、長々とコードを議論しているうちに、あなたの目的は別の方法で解決できることが分かってしまいます。

mql4(とmql5を 少々)を勉強しながら、いろいろとコードを書いて います。これには、配列を使用するコードも含まれます。コードのどこかで配列の項目を 確認する必要があることが多い。ループの中でPrint()を使って行う方法を知りました。しかし、この場合、反復毎に Print()が出力される。繰り返し回数が多いと、プログラムにも読みにも不便です。 一度だけ表示される配列項目の値を持つ Print()ループの外側で Print()を削除しなければ ならないというのは、正しい表現です。あなたの言葉の前に察していました。

Print()をループの外に置くことはすぐに覚えました。そして今、私はPrint()が配列の要素のすべての値を1行で表示する方法を学ぼうとしています。

私のコードの最初のブロックに関して、その方法を説明されました。これまで、一般論として、私はこの技術を理解していました。この方法の詳細を理解するために、これからも頭を悩ませることになるでしょう。
しかし、私のコードの2番目のブロックでは、最初のブロックと異なり、配列要素の値の差分が異なるため、最初のブロックのメソッドは適さないと思われます。
もし私の考えが正しくて、1つ目のブロックの方法が2つ目のブロックに合わないのであれば、1つ目のブロックで行われたのと同じことを、2つ目のブロックに関連して行う方法を教えていただけるとありがたいです。

2つ目のブロックを修正しました。Print() ArraySort()をループの外側に置いてみました。誤解を招かないように、Print() からX変数を削除しています。

int P1=0;
double LoY[31];
void OnTick()
{
if (P1==0)
{
for(int r=0; r<31;r++)
{
LoY[r]=1.6104+(r*2)*0.0001;
P1=1;
}
}
//*************************************************************  Б Л О К    N 2
for(int x=0; x<31;x++)
{
if (Bid < LoY[x] )
{
LoY[x]=Bid;
}
}
ArraySort(LoY,WHOLE_ARRAY,0,MODE_ASCEND);
Print("-LoY[0]-", (знач.эл.масс с инд.0), "---LoY[1]--" ,  (знач.эл.масс с инд.1),   "---LoY[2]--" ,  (знач.эл.масс с инд.2),  "---LoY[3]--" ,  (знач.эл.масс с инд.3),................  "---LoY[30]--" ,  (знач.эл.масс с инд.30) );
}
 
Print("-LoY[0]-", DoubleToString(LoY[0],4), "---LoY[1]--", DoubleToString(LoY[1],4), "---LoY[2]--" , DoubleToString(LoY[2],4), "---LoY[3]--" , DoubleToString(LoY[3],4),................  "---LoY[30]--" ,  DoubleToString(LoY[30],4) );

を作成するか、別途、配列印刷機能を作成します。

void PrintArray(double &eArray)
   {
   string eStr="";
   int eSize=ArraySize(eArray);
   for(int i=0; i<eSize; i++)
      {
      eStr+=IntegerToString(i)+": "+DoubleToString(eArray[i],4)+", ";
      }
   Print(str);
   }

そして、どこからでも呼び出せる

PrintArray(LoY);