前言:
而今你们对“阶乘递归算法时间复杂度”大概比较关怀,咱们都需要分析一些“阶乘递归算法时间复杂度”的相关内容。那么小编同时在网络上汇集了一些有关“阶乘递归算法时间复杂度””的相关资讯,希望看官们能喜欢,小伙伴们一起来了解一下吧!什么是圈复杂度?
—————————————————————————————————————
圈复杂度(Cyclomatic Complexity)是衡量计算机程序复杂程度的一种措施。它根据程序从开始到结束的线性独立路径的数量计算得来的。
圈复杂度越高,代码就越难复杂难维护。坑就越大。。。
从1开始,一直往下通过程序。一但遇到以下关键字,或者其它同类的词,就加1:if,while,repeat,for,and,or。给case语句中的每一种情况都加1。
例如下面这个函数,圈复杂度为1,意味着代码只有一条路径。:
def add(a, b): return a + b
对于有一条分支的代码,它的圈复杂度为 2 ,比如下面递归计算阶乘的代码:
def factorial(n): if n == 0: return 1 else: return n * factorial(n-1)
它的计算方法很简单:
计算公式1:V(G)=E-N+2P。其中,E表示控制流图中边的数量,N表示控制流图中节点的数量,P图的连接组件数目(图的组件数是相连节点的最大集合)。因为控制流图都是连通的,所以P为1.
如何测量程序的圈复杂度?
—————————————————————————————————————
在 Python 中可以使用 mccabe 包测量程序的圈复杂度。
只需要很简单的一行命令即可安装mccabe
pip install mccabe
运行下面这行命令,就可以检测test.py的圈复杂度
python -m mccabe --min 5 test.py
其中 --min 5 是指最小允许的圈复杂度,高于5的圈复杂度则输出出来,如下图:
第一个输出的结果是,91行的roundRobin函数,复杂度为7.
代码质量优化
—————————————————————————————————————
把子程序的一部分提取成另一个子程序,不会降低整个程序的复杂度,只是把决策点移到其他地方,但是这样做可以降低你在同一时间必须关注的复杂度水平。由于重点是要降低你需要在头脑中同时考虑的项目的数量,所以降低一个给定程序的复杂度是有价值的。
1.提炼函数(php为例,下面一样):
function test($number){ if($number < self::MIN_NUMBER) { $number = self::MIN_NUMBER; } for($i = 0; $i < $number; $i++){ //some code }}
可以替换成下面这种模式:
function test($number){ $number = getMin($number); for($i = 0; $i < $number; $i++){ //some code }}function getMin($number){ if($number < self::MIN_NUMBER){ return self::MIN_NUMBER; } return $number}
2.替换算法(把复杂算法替换为另一个更清晰的算法):
if($str == 'China'){ $result = '中国人';}else if($str == 'US'){ $result = '美国人';}else if($str == 'France'){ $result = '法国人';}
变成这样:
$people = [ 'China' => '中国人', 'US' => '美国人', 'France' => '法国人'];$result = $people[$str];
3.逆向表达(调换条件表达顺序达到简化复杂度):
if((条件1 && 条件2) || !条件1){ return true;}else{ return false;}
变成这样:
if(条件1 && !条件2){ return false;}return true;
4.分解条件(对复杂条件表达式(if、else)进行分解并提取成独立函数):
if(do_some_1($number) || do_some_2($number)){ $number = $number.$someStr1.$someStr2.'123456789';}else{ $number = $number.$someStr3.$someStr4.'123456789';}
变成这样:
if(do_some_fun($number)){ $number = do_some_fun1($number);}else{ $number = do_some_fun2($number);}
5.合并条件(将这些判断合并为一个条件式,并提取成独立函数):
if($x < 1) return 0;if($y > 10) return 0;if($z != 0) return 0;
变成这样:
if(get_result($x,$y,$z)) return 0;
6.移除控制标记(可以使用break和return取代控制标记。):
$bool = false;foreach($arrs as $arr){ if(!$bool){ if($arr == 1){ someFunction(); $bool = true; } if($arr == 2){ someFunction(); $bool = true; } }}
变成这样:
foreach($arrs as $arr){ if($arr == 1 || $arr == 2){ someFunction(); } break;}
7.以多态取代条件式(将整个条件式的每个分支放进一个子类的重载方法中,然后将原始函数声明为抽象方法。由于php是弱类型语言,这里体现的有点模糊):
switch ($cat){ case ‘fish’: eatFish(); case ‘moss’: eatMoss();}function eatFish() { echo "Whale eats fish";}function eatMoss() { echo "Whale eat moss";}
变成这样:
interface Eat { function eatFish(); function eatMoss();}class Whale implements Eat { public function eatFish() { echo "Whale eats fish"; } public function eatMoss() { echo "Whale eat moss"; }}
8.参数化方法(建立单一函数,以参数表达那些不同的值):
$result = min(lastUsage(), 100) * 0.03;if(lastUsage() > 100){ $result += (min(lastUsage(), 200) - 100) * 0.05;}
变成这样:
$result = getMin(0,100) * 0.03;$result += getMin(100,200) * 0.03;function getMin($start, $end){ if(lastUsage() > $start){ return (min(lastUsage(),$end) - $start); } return 0;}
9.明确函数取代参数(针对该参数的每一个可能值,建立一个独立函数):
if($name == 'width'){ $width = $value;}else if ($name == 'height'){ $height = $value;}
变成这样:
function setWidth($value){ $width = $value;}function setHeight($value){ $height = $value;}
标签: #阶乘递归算法时间复杂度