关于javascript:手撕代码系列三

2次阅读

共计 3661 个字符,预计需要花费 10 分钟才能阅读完成。

前言

系列首发于公众号『前端进阶圈』,若不想错过更多精彩内容,请“星标”一下,敬请关注公众号最新消息。

手撕代码系列(三)

手写匹配括号 isValid

/**
 * 匹配括号 isValid
 * @param {String} symbolStr 符号字符串
 * @return {Boolean}
 *
 * @logic
 * 1. 定义一个栈数组(stack)
 * 2. 定义字典(obj)
 * 3. 遍历字符串
 * 4. 判断字符串中的每个字符与其对应的符号是否呈现在字典 (obj) 中(如果是无效的,前者与后者是绝对应的)
 * 5. 最初判断,如果栈数组 (stack) 的长度为 0, 则证实是无效的。*/
const isValid = symbolStr => {let stack = [];
    let obj = {'(': ')',
        '[': ']',
        '{': '}',
    };
    for (let i = 0; i < symbolStr.length; i++) {let ele = symbolStr[i];
        // Object.prototype.hasOwnProperty.call(obj, ele):办法是一个罕用的,平安检测对象是否含有某个属性的办法,应用此办法可防止 hasOwnProperty 属性被净化或被重写的危险。if (Object.prototype.hasOwnProperty.call(obj, ele)) {stack.push(ele);
        } else {if (ele != obj[stack.pop()]) return false;
        }
    }
    return !stack.length;
};


// test:
console.log("isValid('(){}') ------>", isValid('(){'));
// isValid('(){}') ------> true
// isValid('(){') ------> false

手写大驼峰转下划线 camelCasetoLineCase

/**
 * 大驼峰转下换线 camelCasetoLineCase
 * @param {String} str 字符串
 * @return 下划线格局字符串
 */
const camelCasetoLineCase = str => {// /([A-Z])/g: 全局匹配大写字母 A-Z
    // $1: 对应正则捕捉到的内容。具体可看下方 demo
    // _$1: 将捕捉的内容采纳下换线的模式并改成小写格局
    return str.replace(/([A-Z])/g, '_$1').toLowerCase();};

// test:
console.log("camelCasetoLineCase('helloWorld') ------>", camelCasetoLineCase('helloWorld')); // camelCasetoLineCase('helloWorld') ------> hello_world

// $1 Demo:
var str = 'Doe, John';
// 阐明:$1,$2 上就是按程序对应小括号外面的小正则 捕捉到的内容
// 把 "Doe, John" 转换为 "John Doe" 的模式
let res = str.replace(/(\w+)\s*, \s*(\w+)/, '$2 $1');
console.log('res ------>', res); // res ------> John Doe

手写下划线转大驼峰 lineCasetocamelCase

/**
 * 下划线转大驼峰 lineCasetocamelCase
 * @param {String} str 须要转换的字符串
 * @return camelCase 格局字符串
 */
const lineCasetocamelCase = str => {
    // \_:将下一个字符标记捕捉到的字符。例如:\n 匹配换行符,\\ 匹配 \,\( 匹配 (// \w: 全局匹配字母、数字、下划线。等价于 [A-Za-z0-9_]
    return str.replace(/\_(\w)/g, (sourceLetter, letter) => {console.log('sourceLetter ------>', sourceLetter, letter); // _w, w
        return letter.toUpperCase();});
};

// test:
console.log("linetoHump('hello_world') ------>", linetoHump('hello_world')); // linetoHump('hello_world') ------> helloWorld

手写反转字符串 reverseStr

/**
 * 反转字符串 reverseStr
 * @param {String} str 须要反转的字符串
 * @return 反转后的字符串
 */
const reverseStr = str => {let strArr = str.split('');
    let left = 0;
    let right = strArr.length;
    while (left <= right) {[strArr[left], strArr[right]] = [strArr[right], strArr[left]];
        left++;
        right--;
    }
    return strArr.join('');
};

// test:
console.log("reverseStr('helloworld') ------>", reverseStr('helloworld')); // reverseStr('helloworld') ------> dlrowolleh

深度优先遍历 DFS(Depth First Search)

/**
 * 深度优先搜寻: DFS(Depth First Search)
 *      深度优先搜寻:也就是一条路走到黑,而后再往回走,看看是否还有其余门路
 *      分类:二叉树的前、中、后序遍历
 *          前序遍历:根节点 -> 左子树 -> 右子树
 *          中序遍历:左子树 -> 根节点 -> 右子树
 *          后序遍历:左子树 -> 右子树 -> 根节点
 */
class Node {constructor(val) {
        this.key = val;
        this.left = null;
        this.right = null;
    }
}
let root = null;
let arr = [];

// 前序遍历:根节点 -> 左节点 -> 右节点
const preOrder = node => {if (node === null) return;
    arr.push(node.key);
    preOrder(node.left);
    preOrder(node.right);
    return arr;
};

// 中序遍历:左节点 -> 根节点 -> 右节点
const inOrder = node => {if (node === null) return;
    inOrder(node.left);
    arr.push(node.key);
    inOrder(node.right);
    return arr;
};

// 后续遍历:左节点 -> 右节点 -> 根节点
const postOrder = node => {if (node === null) return;
    postOrder(node.left);
    postOrder(node.right);
    arr.push(node.key);
    return arr;
};


// test:
root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.right.right = new Node(6);
root.left.left = new Node(4);
root.left.right = new Node(5);
/**
 *  Binary Tree:
          1
       2    3
     4    5   6
 */

// console.log(preOrder(root)); // [1, 2, 4, 5, 3, 6]
// console.log(inOrder(root)); // [4, 2, 5, 1, 3, 6]
// console.log(postOrder(root)); // [4, 5, 2, 6, 3, 1]

特殊字符形容:

  1. 问题标注 Q:(question)
  2. 答案标注 R:(result)
  3. 注意事项规范:A:(attention matters)
  4. 详情形容标注:D:(detail info)
  5. 总结标注:S:(summary)
  6. 剖析标注:Ana:(analysis)
  7. 提醒标注:T:(tips)

    往期举荐:

  8. 前端面试实录 HTML 篇
  9. 前端面试实录 CSS 篇
  10. JS 如何判断一个元素是否在可视区域内?
  11. Vue2、3 生命周期及作用?
  12. 排序算法:QuickSort
  13. 箭头函数与一般函数的区别?
  14. 这是你了解的 CSS 选择器权重吗?
  15. JS 中 call, apply, bind 概念、用法、区别及实现?
  16. 罕用位运算办法?
  17. Vue 数据监听 Object.definedProperty()办法的实现
  18. 为什么 0.1+ 0.2 != 0.3,如何让其相等?
  19. 聊聊对 this 的了解?
  20. JavaScript 为什么要进行变量晋升,它导致了什么问题?

    最初:

  21. 欢送关注『前端进阶圈』公众号,一起摸索学习前端技术 ……
  22. 公众号回复 加群 或 扫码, 即可退出前端交流学习群,一起高兴摸鱼和学习 ……
  23. 公众号回复 加好友,即可添加为好友
正文完
 0