下面的代码接受格式为{Package1: Dependency,Package2: Dependency}的包名和依赖项的数组,并将它们放入要返回的哈希图中。根据我的面试官的说法,该方法的圈复杂度为12,这太高了,无法接受。但是,我对报告复杂度实际上为2的代码运行了度量。
谁能告诉我为什么复杂度会这么高,以及如何简化它以降低圈复杂度?我在这里不知所措。
public static HashMap<String, String> parseDependencies(String[] args) {
HashMap<String, String> pairs = new HashMap<String, String>();
for (int i = 0; i < args.length; i++) {
if (!args[i].contains(": ") || args[i].startsWith(": ")) {
logger.log(Level.WARNING, ENTRY + args[i] + FORMATTING);
continue;
}
String[] entry = args[i].split(": ");
if (entry.length < 2) {
pairs.put(entry[0], null);
} else {
pairs.put(entry[0], entry[1]);
}
}
return pairs;
}发布于 2016-10-30 14:50:50
不同的工具计算圈复杂度略有不同。我不知道面试是如何得出12的,也不知道你是如何得出2的。粗略地说,圈复杂度计算的是条件、循环和控制流语句的数量。你有一个循环,3个条件,一个continue,else,return,结果是7,看起来差不多对了。
这个实现在我看来并不“复杂”,但它有很多问题:
for-
HashMap
entry.length添加第二个参数-1,则可以消除split上的条件。这样,由于args[i].contains(": ")上的早期条件和随后的continue,entry.length将被保证至少为2。
:的重复性不是很好。在这个特定的例子中,我更担心这些事情,而不是圈复杂度。
最后,一种降低圈复杂度的常用技术是将代码提取到助手方法中。例如,复杂的布尔条件,甚至整个循环体。
发布于 2016-10-30 14:49:37
首先,令人惊讶的是,面试官依赖圈复杂度来衡量面试中编写的代码。我不认为我会想在一家经常做这种事情的“商店”里工作。
但是,从CC的角度来看,您的代码可以变得更简单:
public static HashMap<String, String> parseDependencies(String[] args) {
HashMap<String, String> pairs = new HashMap<String, String>();
for (int i = 0; i < args.length; i++) {
String[] entry = args[i].split(": ");
if (entry.length != 2 || entry[0].isEmpty()) {
logger.log(Level.WARNING, ENTRY + args[i] + FORMATTING);
} else if (entry[1].isEmpty()) {
pairs.put(entry[0], null);
} else {
pairs.put(entry[0], entry[1]);
}
}
return pairs;
}逻辑和控制流路径已经简化,这应该会减少CC措施。
(我还利用这个机会纠正了一些明显的错误。)
https://stackoverflow.com/questions/40326559
复制相似问题