复杂逻辑题目的好帮手:注释和断言

前言

最近在刷题的时候,遇到一些逻辑比较复杂的题,往往会遇到困难,经常写不出来。即使在有debug帮助的时候,也往往会出现思虑不周,导致一错再错的情况,即好不容易debug通过一个测试用例,然后发现被另一个测试用例卡住。在周赛双周赛中,这意味着大量的罚时;在工作中,这意味着浪费大量的时间。因此需要有一个方法来辅助思考,完成正确的分类讨论。

注释与断言的作用

人脑的短时存储能力很差(内存/运存很小),因此在处理复杂问题时往往会顾此失彼,此时就需要工具来辅助记录思想(外存)。注释与断言就是起一个这样的作用。

如何使用注释

注释应该给出关键的信息,即一个循环/函数,当进入的时候,关键变量的值应该是什么。当离开的时候,关键变量的值应该是什么。

如何使用断言

即便使用了注释,也不能保证写出的代码在正确的地点有正确的值,此时就需要 assert来自动检验值是否正确。

什么时候使用注释与断言

在刷题/竞赛的时候,为了提高效率,可以采用以下策略:

  • 当刷题时发现自己无法完成分类讨论的时候
  • 当发现自己写的代码有bug的时候
    而当工作或者开发项目的时候,由于越早发现bug代价越小,因此最好从一开始就使用。

例子

以今天的每日一题LC385.迷你语法分析器为例。

复杂逻辑题目的好帮手:注释和断言
如果使用栈+迭代的方法,那么迭代变量就不会出问题,但如果使用递归的方法,那么迭代变量还是容易出问题的。这种情况下,使用注释和断言就可以帮助思考。
/**
 * // This is the interface that allows for creating nested lists.

 * // You should not implement it, or speculate about its implementation
 * public interface NestedInteger {
 *     // Constructor initializes an empty nested list.

 *     public NestedInteger();
 *
 *     // Constructor initializes a single integer.

 *     public NestedInteger(int value);
 *
 *     // @return true if this NestedInteger holds a single integer, rather than a nested list.

 *     public boolean isInteger();
 *
 *     // @return the single integer that this NestedInteger holds, if it holds a single integer
 *     // Return null if this NestedInteger holds a nested list
 *     public Integer getInteger();
 *
 *     // Set this NestedInteger to hold a single integer.

 *     public void setInteger(int value);
 *
 *     // Set this NestedInteger to hold a nested list and adds a nested integer to it.

 *     public void add(NestedInteger ni);
 *
 *     // @return the nested list that this NestedInteger holds, if it holds a nested list
 *     // Return empty list if this NestedInteger holds a single integer
 *     public List getList();
 * }
 */

class Solution {
    public NestedInteger deserialize(String s) {
        char[] cs = s.toCharArray();
        return recur(cs, new int[1]);
    }

    private NestedInteger recur(char[] cs, int[] i) {
        // i[0] must be the start of a token
        if (cs[i[0]] == '[') {
            // this means it's a list
            NestedInteger result = new NestedInteger();
            i[0]++;
            while (cs[i[0]] != ']') {
                // i[0] should be the start of a token
                assert i[0] < cs.length;
                if (cs[i[0]] == ',') {
                    i[0]++; // make sure i[0] is the start of next token
                    continue;
                }
                if (cs[i[0]] == '[' && cs[i[0] + 1] == ']') {
                    // it is a list whose length is 0
                    i[0] += 2; // make sure i[0] is the start of next token
                    result.add(new NestedInteger());
                } else {
                    // it is a list with at least 1 element
                    result.add(recur(cs, i));
                    // the function will make sure i[0] is the start of next token
                }
            }
            // in the end, cs[i[0]] must be ']'
            assert cs[i[0]] == ']';
            i[0]++;  // make sure i[0] is the start of next token
            return result;
        }
        // this is an integer
        int val = 0;
        boolean isNagtive = false;
        if(cs[i[0]] == '-') {
            isNagtive = true;
            i[0]++;
        }
        while(i[0] < cs.length && cs[i[0]] != ',' && cs[i[0]] != ']') {
            assert cs[i[0]] != '[';
            val = val * 10 + cs[i[0]++] - 48;
        }
        // if (i[0] == cs.length) this is the start of next token;
        // if (cs[i[0]] == ',') this is the start of next token;
        // if (cs[i[0]] == ']') this is the end of this token, but should not be process here
        val = isNagtive ? -val : val;
        return new NestedInteger(val);
    }
}

Original: https://www.cnblogs.com/CounterX/p/16151310.html
Author: 计数寄存器
Title: 复杂逻辑题目的好帮手:注释和断言

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/593361/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球