ループ内の条件分岐をなくしたい – プログラミング – Home

ループ内の条件分岐をなくしたい
 
通知
すべてクリア

[解決済] ループ内の条件分岐をなくしたい


boze
 boze
(@boze)
ゲスト
結合: 17年前
投稿: 4
Topic starter  

CやC++に限った話ではないのですが、ご意見をお聞きしたいので
質問させて頂きます。

現在、後述するような関数のように幾つかの条件で処理を分岐しています。
この関数は処理対象(構造体)を変えて数万回実行しますが、
分岐する条件は実行開始時に読み込む設定ファイルで決まるので、
実行される数万回で同じ条件判定をしています。

同じ条件判定を数万回するのは無駄かと思うので、条件の組み合わせ毎に
関数でも作って、設定読み込み後に呼び出し先の処理関数を関数ポインターで
指定してから数万回実行しようかと思っているのですが、条件が1つ増えるたびに
組み合わせが倍になるので、正直面倒臭いなぁとも思っています。

こういった場合どうされていますか?
何かいい方法があれば参考にさせてください。

C++(VC8)で実装しているので、テンプレートなどを使って
シンプルな処理フローになるようなら、そうしたいのですが
自分では考え付きませんでした。

void hoge()
{
if(条件1)
処理1-1
else
処理1-2

if(条件2)
{
処理2-1

if(条件2-1)
処理2-1-1
else
処理2-1-2
}
else
{
処理2-2
}
}


引用未解決
トピックタグ
maru
 maru
(@maru)
ゲスト
結合: 17年前
投稿: 358
 

私なら関数ポインタを使用します。

> 条件が1つ増えるたびに
> 組み合わせが倍になるので、正直面倒臭いなぁとも思っています。
処理を変えるために条件を増やすのだから、それはどんな書き方をしても変わらない
のでは?


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

処理開始前に(条件n)が決定していて、且つ、終了時まで変化しないなら
特に条件が単純だが複合的で、高速性が求められる場合など
関数ポインタを使うのは良くやる手です。

class AAA{
public:
typedef void ( *AAA::Func処理1)( DATA * ex_data);
typedef void ( *AAA::Func処理2)( DATA * ex_data);

 // 事前条件で決まる関数のポインタ
Func処理1 Func処理1Ptr;
Func処理2 Func処理2Ptr;

// 条件ごとの処理関数
void Func処理1_TRUE( DATA * ex_data){}
void Func処理1_FALSE( DATA * ex_data){}
void Func処理2_TRUE( DATA * ex_data){}
void Func処理2_FALSE( DATA * ex_data){}

// 事前条件設定
void ConfigSetUp( int 条件1, int 条件2){
switch( 条件1){
case TRUE: Func処理1Ptr = Func処理1_TRUE; break;
case FALSE: Func処理1Ptr = Func処理1_FALSE; break;
}
switch( 条件2){
case TRUE: Func処理2Ptr = Func処理2_TRUE; break;
case FALSE: Func処理2Ptr = Func処理2_FALSE; break;
}
}

// 実際のオペレーションメイン
 void MainOperation( DATA * ex_data){
Func処理1Ptr( ex_data);
Func処理2Ptr( ex_data);
}
};


返信引用
boze
 boze
(@boze)
ゲスト
結合: 17年前
投稿: 4
Topic starter  

maruさん、仲澤@失業者さん、ご回答ありがとうございます。
やはり、関数ポインタで処理するのが王道なのですね。

質問を投稿後に以下のようなのを考えてみました。
処理関数へのポンターを動的配列にして
条件判定で追加していく仕組みです。

どの程度早くなったか未検証ですが・・・。

class hogehoge
{
private:
typedef void (hogehoge::* FuncPtr)();
std::vector<FuncPtr> m_funcs;

// 処理関数
void func11() { 処理1-1 }
void func12() { 処理1-2 }
void func21() { 処理2-1 }
void func211() { 処理2-1-1 }
void func212() { 処理2-1-2 }
void func22() { 処理2-2 }

public:
// 処理
void Operate()
{
size_t n = m_funcs.size();
for( size_t i = 0; i < n; i++ )
{
(this->*m_funcs[ i ])();
}
}

// 条件設定
void Setup()
{
if(条件1)
m_funcs.push_back( &hogehoge::func11 );
else
m_funcs.push_back( &hogehoge::func12 );

if(条件2)
{
m_funcs.push_back( &hogehoge::func21 );

if(条件2-1)
m_funcs.push_back( &hogehoge::func211 );
else
m_funcs.push_back( &hogehoge::func212 );
}
else
{
m_funcs.push_back( &hogehoge::func22 );
}
}
};


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました