美文网首页
【轻知识】递归、想想你工作用到的递归

【轻知识】递归、想想你工作用到的递归

作者: 言十年 | 来源:发表于2019-04-03 22:27 被阅读0次

可能想到递归,就想到了生兔子、走台阶(这两个应该都是斐波那契吧)、阶乘、二叉树的前中后(深度遍历)、无限分类、打印目录文件。其实我就能想到这么多了。额,等等是不是把汉诺塔忘了。

平常工作中你用到哪些递归了呢?

我说说我的吧。商品分类、商品SKU,然后就没有了。

商品分类无非总是根据子找父类。分类树形展示如何如何。

/**
 * @author yan@yan.com
 * @desc 根据子id获取父ID。通过level指定获取到哪一层的父ID
 * @param int $catId
 * @param int $level 默认追到第一级
 */
public static function getCatIdBySubCatId(int $catId, int $catLevel=1) {
    $where = [
        'where'=>[
            'cate_id'=>$catId
        ]
    ];
    $result = self::find($where);
    if ($result['cate_level'] < $catLevel || empty($result)) { // 说明不符合条件
        return 0;
    }
    if ($result['cate_level'] == $catLevel) {// 如果递归的是目标级别也不要再递了
        return $result['cate_id'];
    }
    return self::getCatIdBySubCatId($result['cate_pid'], $catLevel);
}

还有一个需求是,商品自定义编号。前两位是一级分类的编号,再两位是二级分类的编号。之后四位是该分类(也有可能是三级分类,但是编号止步于二级。但如果只是1级目录下加商品那么一级目录的编号跟00即可,因为没有用到二级。实际上基本都是三级。)下商品的自增的编号。

/**
 * @author yan@yan.com
 * @desc 返回一级二级的分类编号
 * @param int $catId
 * @param int $level
 * @return string
 */
public static function getSerialNumber(int $catId,int $level=0) {
    static $numStr = '';
    if ($level == 0) {
        $numStr = ''; // 第一次调用就将该函数的静态变量给初始化
    }
    $where = [
        'where'=>[
            'cate_id'=>$catId
        ]
    ];
    $result = self::find($where);
    if (empty($result)) {
        return $numStr;
    }
    if ($result['cate_level'] == 1 && $level==0) {
        return $result['serial_number'].'00'; // 如果只是一级类目那么就补00
    } else {
        $numStr = $result['serial_number'].$numStr;
    }
    $result = self::find($where);
    self::getSerialNumber($result['cate_pid'], $level+1);
    return $numStr;
}

那个商品的sku呢。是前端代码(之前有一篇说了下对前端的一次重构)。后来写完觉得就是一个笛卡尔积。效果如下

image.png

其实后来写完之后,也对写的不满意。代码一多就不方便别人看懂了。当然有些优化点,比如解析赋值的特性也会省几行。

assembleSkuList1(data, skuAttr, arr, start) { // 递归组合sku: data 是从服务器获取的 属性list,skuArr是递归后组合的商品的skuList ,arr是不同规格一组,start 其实
  if (data.length === start) { // 递归出口,几个规格就 start
    return skuAttr
  }
  if (data[start].attr_value.length === 0) { // 因为规格 可以删除,这里为了健壮性要加默认值
    const tempObj = {}
    tempObj.attr_id = data[start].attr_id
    tempObj.attr_name = data[start].attr_name
    arr[start] = tempObj
  }
  // 下面是递归的主要逻辑
  for (let i = 0; i < data[start].attr_value.length; i++) {
    arr = deepClone(arr) // 深度拷贝,避免出错
    const tempObj = data[start].attr_value[i]
    tempObj.attr_id = data[start].attr_id
    tempObj.attr_name = data[start].attr_name
    arr[start] = tempObj // 几个规格就几个一组,用arr保存一小组
    if (arr.length === data.length) {
      skuAttr.push({
        sku_attr: arr,
        sku_org_price: this.batchElements.sku_org_price,
        sku_price: this.batchElements.sku_price,
        vip_price: this.batchElements.vip_price,
        sku_stock: this.batchElements.sku_stock,
        weight: this.form.product_weight,
        sku_id: 0
      })
    }
    if (data[start + 1] !== undefined) { // 如果有下一个规格就递归下去,因为 属性是多维
      this.assembleSkuList(data, skuAttr, arr, start + 1)
    }
  }
  return skuAttr
}

写与调

考虑好出口边界。

写那个sku的时候。我先在纸上写了三排规格。然后想怎么组合。然后想到用递归正合适。用笔划了划线。就开始写了。 后来陷入了bug中。又一直用console打印去看打印结果。当然你可以debugger,用鼠标看,但是打印出来的比较直观。

用几个数据先验证。如果正确,尝试用更多的数据。当然像分类跟sku。没多少数据。但可先用四五条,后再用多条。

两个算法动画网站 >https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
https://visualgo.net/en

参考资料:

  • 《数据结构与算法之美》王争(极客时间专栏)

相关文章

  • 【轻知识】递归、想想你工作用到的递归

    可能想到递归,就想到了生兔子、走台阶(这两个应该都是斐波那契吧)、阶乘、二叉树的前中后(深度遍历)、无限分类、打印...

  • 递归

    啥是递归函数? 一个函数通过名字调用自身,这就叫递归函数 写个简单的递归 在平时开发用到的复制对象,也是用到递归 ...

  • Java——归并排序

    在讲解归并排序之前,我们必须先知道什么是递归,因为在归并排序中我们用到了递归。 递归 什么是递归呢?递归方法就是直...

  • 递归用法

    前段时间有个刚学编程的人找我做了几道编程题,都用到了递归,让我写个使用递归的总结,我个人用到的递归不多,就这几道编...

  • PHP遍历某一文件夹下所有文件

    我们用到了递归操作,不懂递归的小伙伴赶紧去google一下。

  • 深究递归和迭代

    深究递归和迭代 使用场景: 需要重复地多次地计算相同的问题,一般会用到递归和循环。 递归: 概念:...

  • Java递归--无限级分类

    递归 一种计算过程,如果其中每一步都要用到前一步或前几步的结果,称为递归的。用递归过程定义的函数,称为递归函数,例...

  • 第三讲 递归(1)

    递归函数是一种自我调用的函数 Python的递归上限是1000左右,太深的递归会报错 f(n+1)的执行结果会用到...

  • vue 组件递归

    组件递归常用到的栗子就比如树形结构的创建,需要自调用进行递归渲染下面是递归组件渲染tree的效果图: 2.调用组件...

  • 589.n-ary-tree-preorder-traversa

    递归 迭代 用到了栈,反向迭代器

网友评论

      本文标题:【轻知识】递归、想想你工作用到的递归

      本文链接:https://www.haomeiwen.com/subject/qrtzbqtx.html