実行結果
C++Builder2007ソースコード
//************************
//***** Unit1.h ********
//************************
//—————————————————————————
#ifndef Unit1H
#define Unit1H
//—————————————————————————
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include “Chart.hpp”
#include “TeEngine.hpp”
#include “TeeProcs.hpp”
#include <ExtCtrls.hpp>
#include “Series.hpp”
#include <vector>
//—————————————————————————
const int max_depth = 100; // 最大階層数
class RecursiveWave
{
public:
int current_depth; // クラスメンバーとして
double Value;
RecursiveWave *child;
RecursiveWave *z_1, *z_2;
int direction; // +1: 順方向、 -1:逆方向
// RecursiveWaveクラスに追加(public) 逆転版(トップダウン用)
bool isTopDownMode;
RecursiveWave(int n, int dir);
void LinkParents(RecursiveWave* parent1, RecursiveWave* parent2); // 後からリンク
void Dump(TMemo *memo);
double GetValue(){ return Value; }
};
std::vector<RecursiveWave*> all_waves;
//—————————————————————————
class TForm1 : public TForm
{
__published: // IDE-managed Components
TChart *Chart1;
TButton *ButtonExit;
TLineSeries *Series1;
TMemo *Memo1;
TLineSeries *Series2;
TButton *Button1;
TRadioGroup *RadioGroup1;
void __fastcall ButtonExitClick(TObject *Sender);
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
RecursiveWave *Top;
void ChartSetting();
};
//—————————————————————————
extern PACKAGE TForm1 *Form1;
//—————————————————————————
#endif
//************************
//***** Unit1.cpp ******
//************************
//—————————————————————————
#include <vcl.h>
#pragma hdrstop
#include <math.h>
#include “Unit1.h”
//—————————————————————————
#pragma package(smart_init)
#pragma link “Chart”
#pragma link “TeEngine”
#pragma link “TeeProcs”
#pragma link “Series”
#pragma resource “*.dfm”
TForm1 *Form1;
//—————————————————————————
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//—————————————————————————
void __fastcall TForm1::ButtonExitClick(TObject *Sender)
{
Close();
}
//—————————————————————————
// ChartSetting
void TForm1::ChartSetting()
{
Chart1->SeriesList->ClearValues();
// 軸タイトルだけ設定(SeriesCountチェックはButton1Click側に移動)
Chart1->LeftAxis->Title->Caption = “Value”;
Chart1->LeftAxis->Title->Visible = true;
Chart1->RightAxis->Title->Caption = “Depth”;
Chart1->RightAxis->Title->Visible = true;
Chart1->RightAxis->Visible = true;
Chart1->BottomAxis->Title->Caption = “Count”;
Chart1->BottomAxis->Visible = true;
}
// ***** 双方向版 *****
RecursiveWave::RecursiveWave(int n, int dir): current_depth(n), Value(0.0), child(NULL),
z_1(NULL), z_2(NULL), direction(dir)
{
if (n >= max_depth) return;
if(direction == -1){
// 子を先に作成(再帰)
child = new RecursiveWave(n + 1, dir);
// all_waves登録
all_waves.push_back(this);
}else if(direction == +1){
// all_wavesに先に登録
all_waves.push_back(this);
// 子を先に作成(再帰)
child = new RecursiveWave(n + 1, dir);
}
}
// 新規ヘルパー関数(トップダウンで親情報を伝播)
void SetupParents(RecursiveWave* node, RecursiveWave* p1, RecursiveWave* p2) {
if (!node) return;
node->LinkParents(p1, p2);
// 子に伝える(z_1 = node自身、z_2 = p1)
SetupParents(node->child, node, p1);
}
// 構築後に親を設定する専用メソッド
void RecursiveWave::LinkParents(RecursiveWave* parent1, RecursiveWave* parent2) {
z_1 = parent1;
z_2 = parent2 ? parent2 : parent1; // z_2がなければz_1で代用
// Valueを親を使って計算
if (z_1) {
Value = z_1->Value * 1.7 – (z_2 ? z_2->Value * 0.97 : 0.0) + 1.0;
} else {
Value = 1.0; // 最上位の初期値
}
}
//**********************
void RecursiveWave::Dump(TMemo *memo)
{
if (all_waves.empty()) return;
AnsiString str;
int count = 0;
for (std::vector<RecursiveWave*>::const_iterator it = all_waves.begin();
it != all_waves.end(); ++it) {
RecursiveWave* neigh = *it;
if (neigh) {
memo->Lines->Add(str.sprintf(“depth= %d, Value= %g”, neigh->current_depth, neigh->Value) );
count++;
}
}
/*memo->Lines->Add(“==============”);
for(int i=0; i<all_waves->size(); i++){
memo->Lines->Add(str.sprintf(“depth= %d, Value= %g”, i, (*all_waves)[i].Value ) );
}*/
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// 既存のオブジェクトをクリア(メモリリーク防止)
for (size_t i = 0; i < all_waves.size(); i++) {
delete all_waves[i];
}
all_waves.clear();
//方向指定、初期化、生成
RecursiveWave *WaveTop;
if(RadioGroup1->ItemIndex == 1){
//順方向
WaveTop = new RecursiveWave(0, +1); // 引数不要!
}else if(RadioGroup1->ItemIndex == 0){
//逆方向
WaveTop = new RecursiveWave(0, -1); // 引数不要!
}
// 再帰的に親リンクを設定(トップダウン)
SetupParents(WaveTop, NULL, NULL); // 新規ヘルパー関数
WaveTop->Dump(Memo1);
ChartSetting();
// Seriesを安全に追加
Chart1->SeriesList->ClearValues(); // 念のため
// Series[0] と Series[1] が確実に存在することを保証
while (Chart1->SeriesCount() < 2) {
TLineSeries* s = new TLineSeries(Chart1);
Chart1->AddSeries(s);
}
int count = 0;
for (std::vector<RecursiveWave*>::const_iterator it = all_waves.begin();
it != all_waves.end(); ++it) {
RecursiveWave* neigh = *it;
if (neigh) {
Chart1->Series[0]->AddY(neigh->Value, “”, clBlue); // Value(左軸)
Chart1->Series[1]->AddY(neigh->current_depth, “”, clRed); // Depth(右軸) ← コメント解除OK
count++;
}
}
// 軸設定を再適用
Chart1->Series[0]->VertAxis = 0; // vaLeft
Chart1->Series[1]->VertAxis = 1; // vaRight
}
//—————————————————————————
