Created
October 31, 2013 11:50
-
-
Save kevinlynx/7248414 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <assert.h> | |
#include <vector> | |
#include <map> | |
class DecisionStmt { | |
public: | |
enum { DECISION_RET = (unsigned) -1 }; | |
typedef std::map<unsigned, int> CondResult; | |
typedef std::vector<CondResult> AccResults; | |
typedef std::vector<unsigned> CondList; | |
public: | |
void addCond(unsigned cond); | |
void enter(); | |
void leave(bool truePart); | |
void coverCond(unsigned condId, bool ret); | |
float compute(); | |
private: | |
AccResults m_rets; | |
CondList m_conds; | |
}; | |
bool matchByConds(unsigned cond, const DecisionStmt::CondResult &r1, const DecisionStmt::CondResult &r2) { | |
auto it = r1.find(cond); | |
auto r2It = r2.find(cond); | |
if (it == r1.end() && r2It == r2.end()) return false; // both are not present | |
if (it == r1.end() && r2It->second == 0 || | |
r2It == r2.end() && it->second == 0) return false; // both are equal 0 | |
if (it->second == r2It->second) return false; // bother are equal 0/1 | |
// now they are different | |
for (auto it = r1.begin(); it != r1.end(); ++it) { | |
if (it->first == cond) continue; | |
auto r2It = r2.find(it->first); | |
if (it->first == DecisionStmt::DECISION_RET) { // decision result | |
assert(r2It != r2.end()); | |
if (it->second == r2It->second) return false; // result equal | |
} else { // condition result | |
if (r2It == r2.end()) return false; // condition result not present | |
if (r2It->second != it->second) return false; // not equal | |
} | |
} | |
return true; | |
} | |
float DecisionStmt::compute() { | |
assert(m_conds.size() > 0); | |
if (m_conds.size() == 1) return 1.f; | |
int match = 0; | |
bool found = false; | |
for (auto cit = m_conds.begin(); cit != m_conds.end(); ++cit) { | |
unsigned cid = *cit; | |
for (auto rit = m_rets.begin(); !found && rit != m_rets.end(); ++rit) { | |
auto &oneRet = *rit; | |
for (auto rit2 = rit + 1; !found && rit2 != m_rets.end(); ++rit2) { | |
if (matchByConds(cid, oneRet, *rit2)) { | |
found = true; | |
} | |
} | |
} | |
if (found) { | |
match ++; | |
found = false; | |
} | |
} | |
return 1.f * match / m_conds.size(); | |
} | |
void DecisionStmt::enter() { | |
CondResult result; | |
m_rets.push_back(result); | |
} | |
void DecisionStmt::leave(bool truePart) { | |
assert(m_rets.size() > 0); | |
auto &result = m_rets.back(); | |
result.insert(std::make_pair((unsigned)DECISION_RET, truePart ? 1 : 0)); | |
} | |
void DecisionStmt::coverCond(unsigned condId, bool ret) { | |
assert(m_rets.size() > 0); | |
auto &result = m_rets.back(); | |
assert(result.find(condId) == result.end()); | |
result[condId] = ret ? 1 : 0; | |
} | |
void DecisionStmt::addCond(unsigned cond) { | |
m_conds.push_back(cond); | |
} | |
int main(int, char **) { | |
DecisionStmt stmt; | |
stmt.addCond(100); | |
stmt.addCond(101); | |
stmt.addCond(102); | |
stmt.addCond(103); | |
// 1 1 1 0 - 0 | |
stmt.enter(); | |
stmt.coverCond(100, true); | |
stmt.coverCond(101, true); | |
stmt.coverCond(102, true); | |
stmt.coverCond(103, false); | |
stmt.leave(false); | |
// 1 0 1 0 - 1 | |
stmt.enter(); | |
stmt.coverCond(100, true); | |
stmt.coverCond(101, false); | |
stmt.coverCond(102, true); | |
stmt.coverCond(103, false); | |
stmt.leave(true); | |
// 1 0 1 1 - 0 | |
stmt.enter(); | |
stmt.coverCond(100, true); | |
stmt.coverCond(101, false); | |
stmt.coverCond(102, true); | |
stmt.coverCond(103, true); | |
stmt.leave(false); | |
// 1 0 0 1 - 1 | |
stmt.enter(); | |
stmt.coverCond(100, true); | |
stmt.coverCond(101, false); | |
stmt.coverCond(102, false); | |
stmt.coverCond(103, true); | |
stmt.leave(true); | |
// 0 1 1 0 - 1 | |
stmt.enter(); | |
stmt.coverCond(100, false); | |
stmt.coverCond(101, true); | |
stmt.coverCond(102, true); | |
stmt.coverCond(103, false); | |
stmt.leave(true); | |
// 0 0 0 0 - 1 | |
stmt.enter(); | |
stmt.coverCond(100, false); | |
stmt.coverCond(101, false); | |
stmt.coverCond(102, false); | |
stmt.coverCond(103, false); | |
stmt.leave(true); | |
printf("%.2f\n", stmt.compute()); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment