2008-10-28 19 views
1

我發現自己寫的代碼看起來像這樣很多:檢查列表和運行處理

set<int> affected_items; 
while (string code = GetKeyCodeFromSomewhere()) 
{ 
    if (code == "some constant" || code == "some other constant") { 
     affected_items.insert(some_constant_id); 
    } else if (code == "yet another constant" || code == "the constant I didn't mention yet") { 
     affected_items.insert(some_other_constant_id); 
    } // else if etc... 
} 
for (set<int>::iterator it = affected_items.begin(); it != affected_items.end(); it++) 
{ 
    switch(*it) 
    { 
     case some_constant_id: 
      RunSomeFunction(with, these, params); 
     break; 
     case some_other_constant_id: 
      RunSomeOtherFunction(with, these, other, params); 
     break; 
     // etc... 
    } 
} 

我結束了寫這個代碼的原因是,我只需要在第二循環中運行的功能甚至一度如果我收到了可能導致它們運行的​​多個鍵碼。

這似乎不是最好的方式來做到這一點。有沒有更好的方法?

回答

1

由於您似乎不關心集合中的實際值,您可以用int中的位設置來替換它。您還可以用日誌時間搜索邏輯替換線性時間搜索邏輯。這是最終的代碼:

// Ahead of time you build a static map from your strings to bit values. 
std::map< std::string, int > codesToValues; 
codesToValues[ "some constant" ] = 1; 
codesToValues[ "some other constant" ] = 1; 
codesToValues[ "yet another constant" ] = 2; 
codesToValues[ "the constant I didn't mention yet" ] = 2; 

// When you want to do your work 
int affected_items = 0; 
while (string code = GetKeyCodeFromSomewhere()) 
    affected_items |= codesToValues[ code ]; 

if(affected_items & 1) 
    RunSomeFunction(with, these, params); 
if(affected_items & 2) 
    RunSomeOtherFunction(with, these, other, params); 
// etc... 
1

它當然不整齊,但你可以保留一組標誌,說明你是否調用了這個特定的函數。這樣你可以避免把東西放在一個集合中,你只需要標記。

由於存在(大概來自它的寫法),編譯時固定編號的不同的if/else塊,您可以使用bitset輕鬆完成此操作。

2

一種方法是維護從字符串到布爾值的映射。主要邏輯可以從類似如下開始:

if(done[code]) 
    continue; 
done[code] = true; 

然後,您可以在識別代碼後立即執行相應的操作。

另一種方法是將某些可執行文件(對象,函數指針等)存儲到某種「待辦事項列表」中。例如:

while (string code = GetKeyCodeFromSomewhere()) 
{ 
    todo[code] = codefor[code]; 
} 

初始化codefor到包含適當的函數指針,或從對象共同的基類的子類,對於每個碼值。如果相同的代碼不止一次出現,todo中的相應條目將會被與已有的相同值覆蓋。最後,重複todo並運行其所有成員。

+0

我喜歡todo-list的想法。 – 2008-10-28 03:29:34

0

很明顯,它將取決於具體情況,但最好讓您調用的函數跟蹤它們是否已經運行並在需要時提前退出。