Halstead 复杂度(Maurice H. Halstead, 1977)是软件科学提出的第一个计算机软件的分析“定律”,用以确定计算机软件开发中的一些定量规律。
Halstead 复杂度采用一组基本的度量值,这些度量值通常在程序源代码产生之后直接得到,或者在设计完成之后进行估算。
完成内容
计算下列代码片段的 Halstead 复杂度的 11 项内容:
1 | if (month < 3) { |
内容说明
难度度量元(Halstead 复杂度)
- Halstead 复杂度根据程序源代码中语句行的操作符和操作数的数量计算程序复杂性。
- 程序源代码中操作符和操作数的量越大,程序难度就越大。
- 操作符通常包括语言保留字、函数调用、运算符,也可以包括有关的分隔符等。
- 操作数可以是常数和变量等标识符。
- Halstead 复杂度度量(设 $n_1$ 表示程序中不同的操作符个数,$n_2$ 表示程序中不同的操作数个数,$N_1$ 表示程序中出现的操作符总数,$N_2$ 表示程序中出现的操作数总数)
- Halstead 程序词汇表长度 Program vocabulary: n = $n_1 + n_2$ .
- Halstead 程序长度或简单长度 Program length: N = $N_1 + N_2$ .
- 注意到 N 定义为 Halstead 长度,并非源代码行数。
- 以 N^ 表示程序的预测长度 Calculated program length:
- N^ = $ n_1 log_2 n_1 + n_2 log_2 n_2$.
- Halstead 的重要结论之一是:程序的实际长度 N 与预测长度 N^ 非常接近,这表明即使程序还未编写完也能预先估算出程序的实际长度 N。
- 程序体积或容量 Volume: V = $Nlog_2 (n)$,表明了程序在词汇上的复杂性。
- 程序级别 Level: L^ = $(2/n_1 ) * (n_2 /N_2)$,表明了一个程序的最紧凑形式的程序量与实际程序量之比,反映了程序的效率。
- 程序难度 Difficulty: D = 1/L^,表明了实现算法的困难程度。
- 编程工作量 Effort: E = V * D = V/L^ .
- 语言级别: Lʹ = (L^) * (L^) * V .
- 编程时间 (hours): T^ = E/(S * f),这里 S = 60 * 60, f = 18 .
- 平均语句大小: N/语句数。
- 程序中的错误数预测值: B = V/3000 = N$log_2$(n)/3000 .
解答
对于题目中的代码片段,可以得到操作符表和操作数表:
Operator | Number of Occurrences |
---|---|
if | 1 |
< | 1 |
+ | 7 |
- | 1 |
= | 2 |
return | 1 |
dayray | 1 |
(int) | 1 |
* | 2 |
/ | 4 |
% | 1 |
Operand | Number of Occurrences |
---|---|
month | 4 |
3 | 1 |
12 | 1 |
year | 6 |
1 | 2 |
day | 1 |
26 | 1 |
10 | 1 |
4 | 1 |
6 | 1 |
100 | 1 |
400 | 1 |
7 | 1 |
所以有,$n_1=11$,$N_1=22$,$n_2=13$,$N_2=22$。
Halstead 程序词汇表长度 Program vocabulary:
- n = $n_1 + n_2$=11+13=24
Halstead 程序长度或简单长度 Program length:
- N = $N_1 + N_2$=22+22=44
以 N^ 表示程序的预测长度 Calculated program length:
N^ = $ n_1 log_2 n_1 + n_2 log_2 n_2$ = $ 11log_2 11 + 13 log_2 13$
=86.15946414084448=86.16
程序体积或容量 Volume:
- V = $Nlog_2(n)$ =$44*log_2(24)$ = 201.7383500317309 = 201.74
程序级别 Level:
L^ = $(2/n_1 ) * (n_2 /N_2)$ = (2/11)*(13/22)
=0.10743801652892562=0.107438
程序难度 Difficulty:
- D = 1/L^ = 1/((2/11)*(13/22)) =9.307692307692307=9.31
编程工作量 Effort:
E = V * D = V/L^ = $44 * log_2(24)/((2/11)*(13/22))$
=1877.7184887568799=1877.72
语言级别:
Lʹ = L^ * L^ * V = $((2/n_1 ) * (n_2 /N_2))^2 * Nlog_2 (n)$
=2.328651127338469=2.33
编程时间 (hours):
T^ = E/(S * f) = $44 * log_2(24)/((2/11)*(13/22)) / (60*60*18)$
= 0.028977137172174074 = 0.028977
平均语句大小:
- 平均语句大小 = N/语句数 = 44/4 = 11
程序中的错误数预测值:
- B = V/3000 = $Nlog_2(n)/3000$ = 0.06724611667724363 = 0.067246