• 剑指offer-高质量的代码


    小结:

    • 规范性:书写清晰、布局清晰、命名合理
    • 完整性:完成基本功能、考虑边界条件、做好错误处理
    • 鲁棒性:采取防御性编程、处理无效输入

    面试这需要关注

    • 输入参数的检查
    • 错误处理和异常的方式(3种)
    • 命名的方式

    需要考虑:功能测试、边界测试(例如超出边界,是大数?)、负面测试(不合法输入)

    错误处理方式(可以与面试官讨论采用什么出错方式适合)

    • 函数用返回值告诉是否出错:使用不方便,不能把这个函数计算结果直接作为参数传递给其他函数
    • 错误发生时设置一个全局变量:调用者容易忽略去检查和处理
    • 异常:抛出和处理

    题-数值的整数次方:需要考虑基数是0还有指数是负数的情况,优化的话可以使用二分递归来求

      细节:右移代替除,位与代替%(n&0×1就是求除以10的余数)

      <string>里面还有个int atoi(const char *str) 函数是用来转化字符串为整数的,如果是这样的串" 232s3112",最后转化为232

    题-打印从1到最大的n位数:要考虑越界,是大数怎么办,所以使用字符串来简单有效表示大数,还需要注重用递归的方法解决问题

    题-删除链表的节点:直接将下一个节点的值复制到要删除的节点,然后改变指针,这样就不用去改要删去的上一个节点了

      两处注意:(1)如果删除的节点是最后的节点;(2)如果删除的节点是头节点;

     题19-正则表达式匹配:画有限状态机来分析有一点帮助

    class Solution {
    public:
        bool match(char* str, char* pattern)
        {
            if(str==nullptr||pattern==nullptr)
                return false;
            return matchcore(str,pattern);
        }
        bool matchcore(char* str, char* pattern){
            if(*str==''&&*pattern=='')  //设置结果的状态,很重要,必须要返回true
                return true;
            if(*str!=''&&*pattern=='')
                return false;
            if(*(pattern+1)=='*'){
                if(*str==*pattern||(*pattern=='.'&&*str!='')) //注意判断str指向的有没有到底很重要
                    return matchcore(str,pattern+2)||matchcore(str+1,pattern)||matchcore(str+1,pattern+2);  //3种状态迁移很重要
                else
                    return matchcore(str,pattern+2); //如果不能匹配那么只能直接跳过×
            }
            if(*str==*pattern||(*pattern=='.'&&*str!=''))
                return matchcore(str+1,pattern+1);
            return false;
        }
    };
    

    题20-表示数值的字符串:表示数值的字符串遵循模式A[.[B]][e|EC]  或者 .B[e|EC]

    题21-调整数组顺序使奇数位于偶数的前面

      要点:设置前后两个指针,如果找到两个不符合的数就交换,O(N),如何可扩展:使用函数指针的参数,即bool (*func)(int),在函数中直接用func表示,在外边具体实现一个比较函数,例如bool isEven(int ),最后在主函数体中,参数该函数的指针。

    3.4代码的鲁棒性

      防御性编程是习惯,最简单的就是在函数入口添加代码以验证用户输入是否符合要求

    题23-链表中环的入口节点:三步(1)两指针设置不同速度,当快指针追上慢指针时代表有环;(2)计算环大小,通过第1步的计数差,或者是再从追上的地方走到下次追到的地方;(3)设置先后相隔环大小的指针遍历,当两个指针指向同一个节点,就是入口节点

    题24-反转链表:设置指针,记录,想好测试用例,防止崩溃、断裂的发生;

    题25-合并两个排序的链表:可以用递归(调用自身,递推加回归)完成合并过程;

    题26-树的子结构:递归,当找到与子结构的根相等的节点,当它就是子结构的根,递归,如果没有成功,从左子树查找,如果不成功,继续查找右子树

      细节:小数的比较不能用==(精度不同,表示有误差),自定义Equal函数,如果差值的绝对值小于10的-7次方就是相等

    class Solution {
    public:
        bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
        {
            if(pRoot1==nullptr||pRoot2==nullptr) return false; //约定空树不是任意一个树的子结构
            bool res=false;
            if(pRoot1->val==pRoot2->val) res=FindSubtree(pRoot1,pRoot2);
            if(!res) res=HasSubtree(pRoot1->left,pRoot2);
            if(!res) res=HasSubtree(pRoot1->right,pRoot2);
            return res;
        }
        bool FindSubtree(TreeNode* pRoot1, TreeNode* pRoot2){
            if(pRoot2==nullptr) return true;
            if(pRoot1==nullptr) return false;
            if(pRoot1->val!=pRoot2->val) return false;
            return FindSubtree(pRoot1->left,pRoot2->left)&&FindSubtree(pRoot1->right,pRoot2->right);
        }
    };
    

      

  • 相关阅读:
    避免数据脏读
    OGG配置文件中参数化的运用
    GoldenGate基于中间队列文件的初始化
    一次linux中毒,挖矿病毒
    goldengate新版本中查看日志读取点
    dlopen用法参数flag介绍
    gdb调试带参数和调试core
    在现有的git服务器上面创建新的repo
    Play Old Diablo 2 on macOS Catalina
    Odoo中的Environment对象
  • 原文地址:https://www.cnblogs.com/zhang-qc/p/8719570.html
Copyright © 2020-2023  润新知