【问题标题】:Reducing Cognitive complexity [closed]降低认知复杂性
【发布时间】:2021-09-22 19:02:07
【问题描述】:

如何降低 while 循环中 if 语句的认知复杂性?这是用于将节点插入线程二叉搜索树的代码。这是我的操作逻辑,但 ide 给了我这些问题。我该如何解决?

重构此方法以将其认知复杂度从 18 降低到允许的 15。 [+11 个地点]

减少此循环中的 break 和 continue 语句总数,最多使用一个。 [+2 个地点]

这是代码

public class threaded {
    class Node{
        Node left;
        boolean lthread;
        int data;
        boolean rthread;
        Node right;

        Node(int data){
            left = null;
            lthread = true;
            this.data = data;
            rthread = true;
            right = null;
        }
    }

    Node root = null;

    void insert(int data){
        Node ptr = root;
        Node par = null;   // parent of the node to be inserted

        while (ptr != null){
            if (data == ptr.data){
                System.out.println("Duplicate key");
                return;
            }

            par = ptr;

            if (data < ptr.data){
                if (!ptr.lthread){
                    ptr = ptr.left;
                }
                else{
                    break;
                }
            }
            else {
                if (!ptr.rthread){
                    ptr = ptr.right;
                }
                else{
                    break;
                }
            }

            Node tmp = new Node(data);  // creating a new node

            if (root == null){
                root = new Node(data);
            }

            else if (data < par.data){
                tmp.left = par.left;
                tmp.right = par;
                par.lthread = false;
                par.left = tmp;
            }

            else if (data > par.data){
                tmp.left = par;
                tmp.right = par.right;
                par.rthread = false;
                par.right = tmp;
            }

        }

    }

【问题讨论】:

  • 如果你不知道这意味着什么,那么我想知道你为什么关心它?
  • 这不是您的代码的问题,必须修复它才能正确运行。这是 IDE 中的一个可选设置,旨在在它认为人类难以阅读代码时向您发出警告。如果您发现代码不难理解,那么您无需关心它,您可以在 IDE 设置中禁用或调整它。 (它不起作用,所以也许它难以遵循?)
  • 你不需要在循环内检查root是否为空,因为你之前设置了ptr = null。重复的else break 也可能是你可以避免的

标签: java sonarlint


【解决方案1】:

认知复杂度衡量您的代码的理解难度。这是一种主观的可维护性检查,用于衡量嵌套的数量和存在的流中断。它与圈复杂度不同(这是逻辑的分支,需要独特的测试用例来测试该代码分支),而是非常接近的表亲。还有一些静态分析可以用来生成认知复杂度分数。

经验法则

想想你需要编写多少个测试用例来测试你的代码。

循环次数,if/else,切换到自己的方法

if 
else  // complexity 2 there can be two paths for this methods

if
  if
  else
else // complexity 4 there are four paths for this method

现在...结合两者...您有多达 8 个条件来测试您的所有代码路径!

在衡量任何事物的复杂性时。想想你需要编写多少测试来测试该方法。您可以通过将复杂性推迟到更小的单元方法来降低认知复杂性。

您的 insert 实施中的一些 cmets 可以帮助您完成您的旅程

void insert(int data){
    Node ptr = root;
    Node par = null;   // parent of the node to be inserted

    while (ptr != null){
        if (data == ptr.data){
            System.out.println("Duplicate key");
            return;
        }

        par = ptr;

        if (data < ptr.data){
            if (!ptr.lthread){ 
                ptr = ptr.left;
            }
            else{ // Exit condition can you handle this in your loop conditional?
                break;
            }
        }
        else {
            if (!ptr.rthread){
                ptr = ptr.right;
            }
            else{ 
                break;
            }
        }

        Node tmp = new Node(data);  // creating a new node

        if (root == null){
            root = new Node(data);
        }

        else if (data < par.data){ // Can you do this in a separate method? -- you might even be able to combine it with your conditions above.
            tmp.left = par.left;
            tmp.right = par;
            par.lthread = false;
            par.left = tmp;
        }

        else if (data > par.data){ // Can you do this in a separate method? append()? if you combine it with your conditional above -- you can go appendLeft(), appendRight()
            tmp.left = par;
            tmp.right = par.right;
            par.rthread = false;
            par.right = tmp;
        }

    }

}

对其进行伪编码以确定您希望如何在插入循环中编写方法。

【讨论】:

  • 只有三个带有if {if else} else的路径
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 1970-01-01
  • 2018-09-19
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多