我想问一个简单的if else语句,它具有多个条件 可以降低圈复杂度吗? 出于目的:
std::string x;
if(cond)
x = "Value1";
else if(cond2)
{
if(cond3)
x = "Value2";
else if(cond4)
x = "Value3";
else
x = "Value4";
}
else if(cond5)
x = "Value6";
else if(cond6)
x = "Value7";
答案 0 :(得分:2)
我不得不用Google搜索它。 Wikipedia说:
循环复杂度是用于指示程序复杂度的软件度量。它是对程序源代码中线性独立路径数量的定量度量。
您可以绘制表格或图形:
*
|
----------------------
| | | |
cond cond2 cond5 cond6
| | | |
x+=1 | x+=5 x+=6
|
-----------------
| | |
cond3 cond4 else
| | |
x+=2 x+=3 x+=4
现在您可以看到没有两个分支会导致相同的结果。如果我们找到导致相同结果的分支,那么我们可以尝试减少路径数量。同样,在没有更多信息的情况下,我必须假设所有条件都是独立的。如果它们之间存在关系,例如cond2 => cond3
,则可以减少分支的数量。
答案 1 :(得分:0)
#include<stdio.h>
int main(){
bool cond,cond1,cond2,cond3,cond4,cond5,cond6;
cond6=true;
int x=10;
x+=cond?1:(cond2?(cond3?2:(cond4?3:4)):(cond5?5:(cond6?6:0)));
printf("%d",x);
}
答案 2 :(得分:0)
您可以使用unsigned int中的位声明属性,并将这些属性组合以定义掩码。 background-position-x: center;
background-position-y: center;
函数使用dispatch
值和x
值来测试这些位并做出相应的响应。
flag
样品运行:
#include <cstdint>
#include <iostream>
// Properties
static constexpr const auto C1 = 1u << 0;
static constexpr const auto C2 = 1u << 1;
static constexpr const auto C3 = 1u << 2;
static constexpr const auto C4 = 1u << 3;
static constexpr const auto C5 = 1u << 4;
static constexpr const auto C6 = 1u << 5;
// Masks (combination of properties)
static constexpr const auto C2C3 = C2 | C3;
static constexpr const auto C2C4 = C2 | C4;
// Dispatch operation based on flag (will jump, not branch)
int dispatch(int x, std::uint32_t flags) {
switch (flags) {
case C1:
return x + 1;
case C2:
return x + 4;
case C2C3:
return x + 2;
case C2C4:
return x + 3;
case C5:
return x + 5;
case C6:
return x + 6;
// add more cases as needed...
default:
// anything not specified is considered an error
throw std::runtime_error("invalid flags");
}
}
#define ASSERT(pred) \
do { \
if (!(pred)) { \
std::cerr << "expected " #pred "\n"; \
} else { \
std::cout << "ok " #pred "\n"; \
} \
} while (false)
#define EXPECT_THROW(pred) \
do { \
bool thrown = false; \
try { \
std::cout << (pred) << "\n"; \
} catch (...) { \
thrown = true; \
} \
if (thrown) { \
std::cout << "ok " #pred "\n"; \
} else { \
std::cerr << "exception not thrown in " #pred "\n"; \
} \
} while (false)
int main() {
// Only these should succeed
ASSERT(dispatch(0, C1) == 1);
ASSERT(dispatch(0, C2) == 4);
ASSERT(dispatch(0, C2C3) == 2);
ASSERT(dispatch(0, C2C4) == 3);
ASSERT(dispatch(0, C5) == 5);
ASSERT(dispatch(0, C6) == 6);
// Anything else should be a failure (there are 2^6 = 64 combinations and only
// 6 should succeed)... only a few are presented
EXPECT_THROW(dispatch(0, C1 | C2));
EXPECT_THROW(dispatch(0, C1 | C3));
EXPECT_THROW(dispatch(0, C3 | C4));
EXPECT_THROW(dispatch(0, C3));
}
可以轻松修改分派功能以添加更多案例。如果属性/标志具有更有意义的名称,那将更加有益。
答案 3 :(得分:-1)
说这整个复杂的代码块在FunctionMain()中,您可以将此代码移到另一个函数中,然后调用该函数。这样,复杂性就转移到了较低级别的功能上,并且可以读取主要代码。
另一种方法是将这段代码中的段拆分为可读的函数。