20回繰り返してみて、それ以上いくらやっても、精度は上がらない。もともとは高精度の計算でやったことはありました。改めて、単純にやってみました。
e=1+1/1!+1/2!+1/3!+...と定義されてますが、定義をそのままコーディングできないので、技術が無いので、階乗の逆数の集計という形でやってみました。
cametan_42さんによれば、数学の定義のままコーディングするのが、再帰関数ということです。For Loopの方は、5からの出力ですが、再帰の方は一項目からの出力で無理がないですね。
問題は、Cametan_42さんのブログにあります。全くスマートでない方法で、書いてみました。
10回ループしてみたら、収束しましたので、答えは多分良いんでしょう。Cametan_42さんは回答に、高階関数とかリスト内表記をイメージしてるようです。
訂正)収束はしそうですが、確認はできてません。最後の出力は同じものでした。その前のものと。
追加)同じ問題に再帰の手続きを入れてみました。
実行の関数名を変更。InOrderBTTraversalKJとします。
InOrderBTTraversalとInOrderBTTraveralJKはFnctionとSubの違いだけです。SubではRetrunは書けないので、コメントアウトしてます。
InOrderBTとInOrderBTTraversalJKの実行結果が同じですので、多分良いと思います。
配列では少し無理そうなので、Queue(キュー)というデータ構造が有るようです。配列だと、添字が必須ですが、Queueは要りません。Stackと同じ感覚で使えそうです。
queにデータを入れるのは、中程の一箇所で良いと思います。queはByRefで受け取りますが、Return queは要らない気もしますが、FunctionはReturnが必要です。
実行の画面では、違いがわかりませんが、Mainを見れば、違いがわかると思います。多分ですが、queは配列と同じく扱えると思います。queはQueueでしたが、例えばstk(Stack)を使えば、降順になりそうです。
InOrderCpyがメソッドになったので、呼び出し方法が変わります。root.InOrderCpy()となります。
InOrderCpyをメソッドに変えました。Thenのあとも、上のように変わります。
でも既に、同じメソッドがありました。PrintTreeInOrder()。全く同じ。あっちこち参考にしているので、被ったかも。
上はPythonの例ですが、気になったのが、inorderTraversalです。PrintTreeは単に出力するだけですが、inorderTraversalは配列、リストをreturnしてます。しかもrecursiveで、res=[]とありますので、呼ばれるたびに宣言されてるんですね。これってVBでやれますか?少なくとも、Pythonのappendみたいには出来ないと思いますが、どおですかね?次に調べてみたいと思います。
最近のVisual Basic では、Propertyが楽に書けます。少し前の例では、GetとSetを使ってましたが、下のように書けます。クラスのインスタンスはNewで作りますが、コンストラクタを定義してます。例えばInteger等では、Newを使わなくても、変数を確保できますが、使っても出来たと思います。逆にClassのインスタンスは使わないと、確保できない。だったと思います。
変数dbgを定義して、コメントは表示から外しました。
rootを定義します。子は無し。実行は下の図。PrintはInOrderCpyで行いますが、もとはInOrderでClass binarytreeに有ったものです。名前が同じだと、まずいのでCpyを付けました。Class binarytreeは今は使いませんので、図にありません。注目は、recuresiveになっているところです。RightNodeとLeftNodeともNothingなのでmyNode.Valueを出力して終わりです。一番下のNodeは「葉」とか言うみたいですが、.Valueは有るんですね。この例の場合だと、出力はConosole.WriteLineなので不味く感じる人もいるかも知れません。
今思ったのですが、myNodeとは何でしょう。普通に考えれば、暗黙のインスタンスであれば、例えばPythonであれば、this.Valueとかだと思いますが、なんか勘違いしているのかもしれません。
追記)InOrderCpyは、一般の関数として定義されてます。メソッド(メンバ関数)として定義すれば、root.InOrder()と書けるんしょうか?
Class Nodeは、BinaryTreeの根幹。いちばん大事なところですね。前のVisual Basic の例だとClass binarytreeを作ってましたが、どうも必須でないようですので、NodeとMainだけでやってみます。
数字だけだと、BinaryTreeに繋げられないので、Change2Nodeで変換します。結果は、rootの値は10で、小さいものは左に繋いでいきます。大きいものは、右に。PrintTreeは小さい順に、出力されます。
元のデータはPythonで書いてあるのですが、なかなかコピペが素直に行きません。インデントが崩れると意味が違ってしまうのが、自分には合わない。素直にVisual Basic のようにガイドしてくれる方が楽です。
insertはこれで完結なのが嬉しいですね。もともとはRPNの利用から、出来ると有ったのですが、それは不明です。キーが同じ値では、駄目ですが、BinaryTree自体がソート済みなのが利点なんでしょうかね。
出力の方法が、3つほどあるらしいので、やってみようかなあ、と思ってます。参考まで、FC2wordpressにコードを貼り付けています。
一番身近にあったのが、林晴比古さんの「C言語による実用アルゴリズム」のバイナリーツリーの説明です。多少読んでみると、mallocなどのメモリの割当が出てきます。これってVBで出来ないのかもと思いながら、ネットを探していました。するとアメリカですかね。ありました。日本語でなかったのですが、実行まで行けました。コメントだけをグーグル翻訳で訳しました。林さんの説明が詳しくて、分かりやすいと思います。話的には分かりやすいのと、それをコードにしたときとはまた、少し違います。
上二枚がNodeClassです。
長いの混乱してるかもしれません。
上一枚がメイン。コードは拾ったものですが、fc2ブログへ貼り付けてます。
デバッグはDim inpstr as Stringの文、でチェックしましたが、冪乗が少し他と違って、a ^ b ^ cであればa ^ ( b ^ c)と置換えないと、間違ってしまうようです。他の演算子は左から見ていけば良いのですが、冪乗は右から見ていかないとだめなのかもしれません。
Function DoPopUntilLeftParaの下側のReturnは到達しないと思いますが、無いとエラーだったと思います。ByRefで引数を指定しないと、駄目だったと思います。rpnstrはそうですが、opeStackは多分アドレスを渡しているように思いますが…。fc2WordPressにコードを貼り付けています
Propertyの設定を普通にやると、煩雑です。自動実装Propertyというのがあるようです。
たしかに短くはなりますね。その代わりにDim a As String = _Opとか、不明の文が入ります。FC2WordPressにコードを貼り付けています。
クラスのメンバ変数は、普通Privateにして、アクセス関数を作ります。それを実現するのがPropertyのようです。多少長ったらしくなりますが、メンバ変数を保護する意味合いはあるんでしょうね。いろんなが言語で同じようです。次回はこれをRPNの作成に適用してみます。