JavaScript刷LeetCode模板技巧篇(一)
虽然很多人都觉得前端算法弱,但其实 JavaScript 也可以刷题啊!最近两个月断断续续刷完了 leetcode 前 200 的 middle + hard ,总结了一些刷题常用的模板代码。
常用函数
包括打印函数和一些数学函数。
const _max = Math.max.bind(Math);
const _min = Math.min.bind(Math);
const _pow = Math.pow.bind(Math);
const _floor = Math.floor.bind(Math);
const _round = Math.round.bind(Math);
const _ceil = Math.ceil.bind(Math);
const log = console.log.bind(console);
//const log = _ => {}
log
在提交的代码中当然是用不到的,不过在调试时十分有用。但是当代码里面加了很多 log
的时候,提交时还需要一个个注释掉就相当麻烦了,只要将log
赋值为空函数就可以了。
举一个简单的例子,下面的代码是可以直接提交的。
// 计算 1+2+...+n
// const log = console.log.bind(console);
const log = _ => {}function sumOneToN(n) {let sum = 0;for (let i = 1; i <= n; i++) {sum += i;log(`i=${i}: sum=${sum}`);}return sum;
}sumOneToN(10);
位运算的一些小技巧
判断一个整数 x
的奇偶性:x & 1 = 1 (奇数) , x & 1 = 0 (偶数)
求一个浮点数 x
的整数部分:~~x
,对于正数相当于 floor(x)
对于负数相当于 ceil(-x)
计算 2 ^ n
:1 << n
相当于 pow(2, n)
计算一个数 x
除以 2 的 n 倍:x >> n
相当于 ~~(x / pow(2, n))
判断一个数 x
是 2 的整数幂(即 x = 2 ^ n): x & (x - 1) = 0
※注意※:上面的位运算只对32位带符号的整数有效,如果使用的话,一定要注意数!据!范!围!
记住这些技巧的作用:
提升运行速度 ❌
提升逼格 ✅
举一个实用的例子,快速幂(原理自行google)
// 计算x^n n为整数
function qPow(x, n) {let result = 1;while (n) {if (n & 1) result *= x; // 同 if(n%2)x = x * x;n >>= 1; // 同 n=floor(n/2)}return result;
}
链表
刚开始做 LeetCode 的题就遇到了很多链表的题。恶心心。最麻烦的不是写题,是调试啊!!于是总结了一些链表的辅助函数。
/** * 链表节点 * @param {*} val* @param {ListNode} next*/
function ListNode(val, next = null) {this.val = val;this.next = next;
}
/** * 将一个数组转为链表 * @param {array} a* @return {ListNode} */
const getListFromArray = (a) => {let dummy = new ListNode()let pre = dummy;a.forEach(x => pre = pre.next = new ListNode(x));return dummy.next;
}
/** * 将一个链表转为数组 * @param {ListNode} node* @return {array} */
const getArrayFromList = (node) => {let a = [];while (node) {a.push(node.val);node = node.next;}return a;
}
/** * 打印一个链表 * @param {ListNode} node */
const logList = (node) => {let str = 'list: ';while (node) {str += node.val + '->';node = node.next;}str += 'end';log(str);
}
还有一个常用小技巧,每次写链表的操作,都要注意判断表头,如果创建一个空表头来进行操作会方便很多。
let dummy = new ListNode();
// 返回
return dummy.next;
使用起来超爽哒~举个例子。@leetcode 82。题意就是删除链表中连续相同值的节点。
/** * @param {ListNode} head* @return {ListNode} */
var deleteDuplicates = function(head) {// 空指针或者只有一个节点不需要处理if (head === null || head.next === null) return head;let dummy = new ListNode();let oldLinkCurrent = head;let newLinkCurrent = dummy;while (oldLinkCurrent) {let next = oldLinkCurrent.next;// 如果当前节点和下一个节点的值相同 就要一直向前直到出现不同的值if (next && oldLinkCurrent.val === next.val) {while (next && oldLinkCurrent.val === next.val) {next = next.next;}oldLinkCurrent = next;} else {newLinkCurrent = newLinkCurrent.next = oldLinkCurrent;oldLinkCurrent = oldLinkCurrent.next;}}newLinkCurrent.next = null; // 记得结尾置空~logList(dummy.next);return dummy.next;
};deleteDuplicates(getListFromArray([1,2,3,3,4,4,5]));
deleteDuplicates(getListFromArray([1,1,2,2,3,3,4,4,5]));
deleteDuplicates(getListFromArray([1,1]));
deleteDuplicates(getListFromArray([1,2,2,3,3]));
参考视频:传送门
本地运行结果
list: 1->2->5->end
list: 5->end
list: end
list: 1->end
是不是很方便!
矩阵(二维数组)
矩阵的题目也有很多,基本每一个需要用到二维数组的题,都涉及到初始化,求行数列数,遍历的代码。于是简单提取出来几个函数。
/*** 初始化一个二维数组* @param {number} r 行数* @param {number} c 列数* @param {*} init 初始值*/
const initMatrix = (r, c, init = 0) => new Array(r).fill().map(_ => new Array(c).fill(init));
/*** 获取一个二维数组的行数和列数* @param {any[][]} matrix* @return [row, col]*/
const getMatrixRowAndCol = (matrix) => matrix.length === 0 ? [0, 0] : [matrix.length, matrix[0].length];
/*** 遍历一个二维数组* @param {any[][]} matrix * @param {Function} func */
const matrixFor = (matrix, func) => {matrix.forEach((row, i) => {row.forEach((item, j) => {func(item, i, j, row, matrix);});})
}
/*** 获取矩阵第index个元素 从0开始* @param {any[][]} matrix * @param {number} index */
function getMatrix(matrix, index) {let col = matrix[0].length;let i = ~~(index / col);let j = index - i * col;return matrix[i][j];
}
/*** 设置矩阵第index个元素 从0开始* @param {any[][]} matrix * @param {number} index */
function setMatrix(matrix, index, value) {let col = matrix[0].length;let i = ~~(index / col);let j = index - i * col;return matrix[i][j] = value;
}
找一个简单的矩阵的题示范一下用法。@leetcode 566。题意就是将一个矩阵重新排列为r行c列。
/** * @param {number[][]} nums* @param {number} r* @param {number} c* @return {number[][]} */
var matrixReshape = function(nums, r, c) {// 将一个矩阵重新排列为r行c列// 首先获取原来的行数和列数let [r1, c1] = getMatrixRowAndCol(nums);log(r1, c1);// 不合法的话就返回原矩阵if (!r1 || r1 * c1 !== r * c) return nums;// 初始化新矩阵let matrix = initMatrix(r, c);// 遍历原矩阵生成新矩阵matrixFor(nums, (val, i, j) => {let index = i * c1 + j; // 计算是第几个元素log(index);setMatrix(matrix, index, val); // 在新矩阵的对应位置赋值});return matrix;
};let x = matrixReshape([[1],[2],[3],[4]], 2, 2);
log(x)
二叉树
当我做到二叉树相关的题目,我发现,我错怪链表了,呜呜呜这个更恶心。
当然对于二叉树,只要你掌握先序遍历,后序遍历,中序遍历,层序遍历,递归以及非递归版,先序中序求二叉树,先序后序求二叉树,基本就能AC大部分二叉树的题目了(我瞎说的)。
二叉树的题目 input 一般都是层序遍历的数组,所以写了层序遍历数组和二叉树的转换,方便调试。
function TreeNode(val, left = null, right = null) {this.val = val;this.left = left;this.right = right;
}
/*** 通过一个层次遍历的数组生成一棵二叉树* @param {any[]} array* @return {TreeNode}*/
function getTreeFromLayerOrderArray(array) {let n = array.length;if (!n) return null;let index = 0;let root = new TreeNode(array[index++]);let queue = [root];while(index < n) {let top = queue.shift();let v = array[index++];top.left = v == null ? null : new TreeNode(v);if (index < n) {let v = array[index++];top.right = v == null ? null : new TreeNode(v);}if (top.left) queue.push(top.left);if (top.right) queue.push(top.right);}return root;
}
/*** 层序遍历一棵二叉树 生成一个数组* @param {TreeNode} root * @return {any[]}*/
function getLayerOrderArrayFromTree(root) {let res = [];let que = [root];while (que.length) {let len = que.length;for (let i = 0; i < len; i++) {let cur = que.shift();if (cur) {res.push(cur.val);que.push(cur.left, cur.right);} else {res.push(null);}}}while (res.length > 1 && res[res.length - 1] == null) res.pop(); // 删掉结尾的 nullreturn res;
}
一个例子,@leetcode 110,判断一棵二叉树是不是平衡二叉树。
/** * @param {TreeNode} root * @return {boolean} */
var isBalanced = function(root) {if (!root) return true; // 认为空指针也是平衡树吧// 获取一个二叉树的深度const d = (root) => {if (!root) return 0;return _max(d(root.left), d(root.right)) + 1;}let leftDepth = d(root.left);let rightDepth = d(root.right);// 深度差不超过 1 且子树都是平衡树if (_min(leftDepth, rightDepth) + 1 >= _max(leftDepth, rightDepth)&& isBalanced(root.left) && isBalanced(root.right)) return true;return false;
};log(isBalanced(getTreeFromLayerOrderArray([3,9,20,null,null,15,7])));
log(isBalanced(getTreeFromLayerOrderArray([1,2,2,3,3,null,null,4,4])));
二分查找
参考 C++ STL 中的 lower_bound
和 upper_bound
。这两个函数真的很好用的!
/** * 寻找>=target的最小下标 * @param {number[]} nums* @param {number} target* @return {number} */
function lower_bound(nums, target) {let first = 0;let len = nums.length;while (len > 0) {let half = len >> 1;let middle = first + half;if (nums[middle] < target) {first = middle + 1;len = len - half - 1;} else {len = half;}}return first;
}/** * 寻找>target的最小下标 * @param {number[]} nums* @param {number} target* @return {number} */
function upper_bound(nums, target) {let first = 0;let len = nums.length;while (len > 0) {let half = len >> 1;let middle = first + half;if (nums[middle] > target) {len = half;} else {first = middle + 1;len = len - half - 1;}}return first;
}
照例,举个例子,@leetcode 34。题意是给一个排好序的数组和一个目标数字,求数组中等于目标数字的元素最小下标和最大下标。不存在就返回 -1。
/** * @param {number[]} nums* @param {number} target* @return {number[]} */
var searchRange = function(nums, target) {let lower = lower_bound(nums, target);let upper = upper_bound(nums, target);let size = nums.length;// 不存在返回 [-1, -1]if (lower >= size || nums[lower] !== target) return [-1, -1];return [lower, upper - 1];
};
在 VS Code 中刷 LeetCode
前面说的那些模板,难道每一次打开新的一道题都要复制一遍么?当然不用啦。
首先配置代码片段 选择 Code -> Preferences -> User Snippets ,然后选择 JavaScript
然后把文件替换为下面的代码:
{"leetcode template": {"prefix": "@lc","body": ["const _max = Math.max.bind(Math);","const _min = Math.min.bind(Math);","const _pow = Math.pow.bind(Math);","const _floor = Math.floor.bind(Math);","const _round = Math.round.bind(Math);","const _ceil = Math.ceil.bind(Math);","const log = console.log.bind(console);","// const log = _ => {}","/**************** 链表 ****************/","/**"," * 链表节点"," * @param {*} val"," * @param {ListNode} next"," */","function ListNode(val, next = null) {"," this.val = val;"," this.next = next;","}","/**"," * 将一个数组转为链表"," * @param {array} array"," * @return {ListNode}"," */","const getListFromArray = (array) => {"," let dummy = new ListNode()"," let pre = dummy;"," array.forEach(x => pre = pre.next = new ListNode(x));"," return dummy.next;","}","/**"," * 将一个链表转为数组"," * @param {ListNode} list"," * @return {array}"," */","const getArrayFromList = (list) => {"," let a = [];"," while (list) {"," a.push(list.val);"," list = list.next;"," }"," return a;","}","/**"," * 打印一个链表"," * @param {ListNode} list "," */","const logList = (list) => {"," let str = 'list: ';"," while (list) {"," str += list.val + '->';"," list = list.next;"," }"," str += 'end';"," log(str);","}","/**************** 矩阵(二维数组) ****************/","/**"," * 初始化一个二维数组"," * @param {number} r 行数"," * @param {number} c 列数"," * @param {*} init 初始值"," */","const initMatrix = (r, c, init = 0) => new Array(r).fill().map(_ => new Array(c).fill(init));","/**"," * 获取一个二维数组的行数和列数"," * @param {any[][]} matrix"," * @return [row, col]"," */","const getMatrixRowAndCol = (matrix) => matrix.length === 0 ? [0, 0] : [matrix.length, matrix[0].length];","/**"," * 遍历一个二维数组"," * @param {any[][]} matrix "," * @param {Function} func "," */","const matrixFor = (matrix, func) => {"," matrix.forEach((row, i) => {"," row.forEach((item, j) => {"," func(item, i, j, row, matrix);"," });"," })","}","/**"," * 获取矩阵第index个元素 从0开始"," * @param {any[][]} matrix "," * @param {number} index "," */","function getMatrix(matrix, index) {"," let col = matrix[0].length;"," let i = ~~(index / col);"," let j = index - i * col;"," return matrix[i][j];","}","/**"," * 设置矩阵第index个元素 从0开始"," * @param {any[][]} matrix "," * @param {number} index "," */","function setMatrix(matrix, index, value) {"," let col = matrix[0].length;"," let i = ~~(index / col);"," let j = index - i * col;"," return matrix[i][j] = value;","}","/**************** 二叉树 ****************/","/**"," * 二叉树节点"," * @param {*} val"," * @param {TreeNode} left"," * @param {TreeNode} right"," */","function TreeNode(val, left = null, right = null) {"," this.val = val;"," this.left = left;"," this.right = right;","}","/**"," * 通过一个层次遍历的数组生成一棵二叉树"," * @param {any[]} array"," * @return {TreeNode}"," */","function getTreeFromLayerOrderArray(array) {"," let n = array.length;"," if (!n) return null;"," let index = 0;"," let root = new TreeNode(array[index++]);"," let queue = [root];"," while(index < n) {"," let top = queue.shift();"," let v = array[index++];"," top.left = v == null ? null : new TreeNode(v);"," if (index < n) {"," let v = array[index++];"," top.right = v == null ? null : new TreeNode(v);"," }"," if (top.left) queue.push(top.left);"," if (top.right) queue.push(top.right);"," }"," return root;","}","/**"," * 层序遍历一棵二叉树 生成一个数组"," * @param {TreeNode} root "," * @return {any[]}"," */","function getLayerOrderArrayFromTree(root) {"," let res = [];"," let que = [root];"," while (que.length) {"," let len = que.length;"," for (let i = 0; i < len; i++) {"," let cur = que.shift();"," if (cur) {"," res.push(cur.val);"," que.push(cur.left, cur.right);"," } else {"," res.push(null);"," }"," }"," }"," while (res.length > 1 && res[res.length - 1] == null) res.pop(); // 删掉结尾的 null"," return res;","}","/**************** 二分查找 ****************/","/**"," * 寻找>=target的最小下标"," * @param {number[]} nums"," * @param {number} target"," * @return {number}"," */","function lower_bound(nums, target) {"," let first = 0;"," let len = nums.length;",""," while (len > 0) {"," let half = len >> 1;"," let middle = first + half;"," if (nums[middle] < target) {"," first = middle + 1;"," len = len - half - 1;"," } else {"," len = half;"," }"," }"," return first;","}","","/**"," * 寻找>target的最小下标"," * @param {number[]} nums"," * @param {number} target"," * @return {number}"," */","function upper_bound(nums, target) {"," let first = 0;"," let len = nums.length;",""," while (len > 0) {"," let half = len >> 1;"," let middle = first + half;"," if (nums[middle] > target) {"," len = half;"," } else {"," first = middle + 1;"," len = len - half - 1;"," }"," }"," return first;","}","$1"],"description": "LeetCode常用代码模板"}
}
以后每一次写题之前,键入 @lc
就会出现提示,轻松加入代码模板。
相关文章:

JavaScript刷LeetCode模板技巧篇(一)
虽然很多人都觉得前端算法弱,但其实 JavaScript 也可以刷题啊!最近两个月断断续续刷完了 leetcode 前 200 的 middle hard ,总结了一些刷题常用的模板代码。 常用函数 包括打印函数和一些数学函数。 const _max Math.max.bind(Math); co…...

ros-sensor_msgs/PointCloud2消息内容解释
1.字段解释 header-----头文件,包含消息的序列号,时间戳(系统时间)和坐标系id,其中secs为秒,nsecs为去除秒数后剩余的纳秒数 height-----点云的高度,如果是无序点云,则为1,例子中的点云为有序点…...

LeetCode 每日一题2347. 最好的扑克手牌
Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接 我会一直往里填充内容哒! &…...

MMPBSA计算--基于李继存老师gmx_mmpbsa脚本
MMPBSA计算–基于李继存老师gmx_mmpbsa脚本 前期准备 软件安装 安装gromacs, 可以查阅 我的blogGromacs-2022 GPU-CUDA加速版 unbantu 安装 apbs, sudo apt install apbs 安装 gawk, sudo apt install gawk MD模拟好的文件 我们以研究蛋白小分子动态相互作用-III(蛋白配体…...

Kafka优化篇-压测和性能调优
简介 Kafka的配置详尽、复杂,想要进行全面的性能调优需要掌握大量信息,这里只记录一下我在日常工作使用中走过的坑和经验来对kafka集群进行优化常用的几点。 Kafka性能调优和参数调优 性能调优 JVM的优化 java相关系统自然离不开JVM的优化。首先想到…...

MinIo-SDK
3.2.5 SDK 3.2.5.1上传文件 MinIO提供多个语言版本SDK的支持,下边找到java版本的文档: 地址:https://docs.min.io/docs/java-client-quickstart-guide.html 最低需求Java 1.8或更高版本: maven依赖如下: XML<dependency&g…...
系统分析师真题2018试卷相关概念一
面向对象的基本概念: 对象的三要素为:属性(数据)、方法(操作)、对象ID(标识)UML2.0包括14种图: 类图(class diagram):类图描述一组类、接口、协作和他们之间的关系。在OO系统的建模中,最常见的图就是类图。类图给出了系统的静态设计图,活动类的类图给出了系统的静…...

身为大学生,你不会还不知道有这些学生福利吧!!!!
本文介绍的是利用学生身份可以享受到的相关学生优惠权益,但也希望各位享受权利的同时不要忘记自己的义务,不要售卖、转手自己的学生优惠资格,使得其他同学无法受益。 前言 高考已经过去,我们也将迎来不同于以往的大学生活&#x…...
试题 算法训练 藏匿的刺客
问题描述 强大的kAc建立了强大的帝国,但人民深受其学霸及23文化的压迫,于是勇敢的鹏决心反抗。 kAc帝国防守森严,鹏带领着小伙伴们躲在城外的草堆叶子中,称为叶子鹏。 kAc帝国的派出的n个看守员都发现了这一问题ÿ…...

JavaWab开发的总括以及HTML知识
一、Web开发的总括在这里我来给大家介绍一下Wab开发需要配合哪些前后端的对应语言:首先是Java(Java通常的工作):Wab开发android开发大数据开发另外,Wab开发想要学好就需要配合之前博客中的内容,如:多线程/IO/网络/数据结构/数据库......这里建议学懂前面的内容再往下走.JavaWab…...
Oracle数据库文件(*.dbf)迁移【图文教程】
目录 背景 解决 第1步:sqlplus登录 第2步:查看Oracle数据文件所在目录 第3步:修改表空间为离线状态 第4步: 移动数据库文件到新目录 第5步:修改表空间数据文件位置 第6步:修改表空间为online状态 第7步:临时表空间处理 第8步:验证修改是否成功 参考...

Java中如何创建和使用对象?
要想使用一个类则必须要有对象。在Java程序中可以使用new关键字创建对象,具体格式如下:类名对象名称null; 对象名称new 类名();上述格式中,创建对象分为声明对象和实例化对象两步,也可以直接通过下面的方式创建对象,具…...

Spring Cloud Alibaba--ActiveMQ微服务详解之消息队列(四)
上篇讲述高并发情况下的数据库处理方式:分布式事务管理机制。即使我们做到这一步并发情况只能稍微得到缓解,当然千万级别的问题不大,但在面对双十一淘宝这类的达上亿的并发的时候仅仅靠分布式事务管理还是远远不够,即使数据库可以…...

32岁,薪水被应届生倒挂,裸辞了
今年 32 岁,我从公司离职了,是裸辞。 前段时间,我有一件事情一直憋在心里很难受,想了很久也没找到合适的人倾诉,就借着今天写出来。 我一个十几年开发经验,八年 软件测试 经验的职场老人,我慢…...

蓝桥杯训练day1
前缀和差分1.前缀和(1)3956. 截断数组(2)795. 前缀和(3)796. 子矩阵的和(4)1230. K倍区间(5)99. 激光炸弹2.差分(1)797. 差分(2)差分矩阵(3)3729. 改变数组元素(4)100. 增减序列1.前缀和 (1)3956. 截断数组 方法1:暴力 先用两个数组分别保存前缀和,后缀…...

Unity毛发系统TressFX Exporter
Unity 数字人交流群:296041238 一:在Maya下的TressFX Exporter 插件安装步骤: 1. 下载Maya的TressFX Exporter插件 下载地址:TressFX Exporter 链接:https://github.com/Unity-China/cn.unity.hairfx.core/tree/m…...

《爆肝整理》保姆级系列教程python接口自动化(十九)--Json 数据处理---实战(详解)
简介 上一篇说了关于json数据处理,是为了断言方便,这篇就带各位小伙伴实战一下。首先捋一下思路,然后根据思路一步一步的去实现和实战,不要一开始就盲目的动手和无头苍蝇一样到处乱撞,撞得头破血流后而放弃了。不仅什么…...
Golang:reflect反射的使用例子
1.reflect包作用 reflect包定义了“反射”相关能力,“反射”在计算机学中是指计算机程序在运行时(runtime)可以访问、检测和修改它本身状态或行为的一种能力。基于反射特性可以通用化地解决一些需要频繁修改代码及硬编码问题,但是…...

markdown常用语法--花括号(超详细)
💌 所属专栏:【Markdown常用语法】 😀 作 者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! …...

BN、SyncBN、IN、LN、GN学习记录
1 BatchNormBN的原理BN是计算机视觉最常用的标准化方法,它沿着N、H、W维度对输入特征图求均值和方差,随后再利用均值和方差来归一化特征图。计算过程如下图所示,1)沿着通道维度计算其他维度的均值;2)沿着通…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...