Zh某的备忘录

记录生活点滴

这篇文章仍处在更新当中。

本文中所有排序算法均使用Javascript实现,且均为升序排序

选择排序

  • 遍历数组元素(忽略已经排序过的),找到最小的放到最前面
1
2
3
4
5
6
7
8
9
10
11
function selectionSort(arr) {
for (let i = 0; i < arr.length - 1; i++) {
let min = i;
for (let j = i; j < arr.length; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
[arr[i], arr[min]] = [arr[min], arr[i]];
}
}

冒泡排序

  • 遍历数组元素,比较相邻元素,大的“冒泡”到后面
1
2
3
4
5
6
7
8
9
function bubbleSort(arr) {
for (let i = 0; i < arr.length - 1; i++) {
for (let j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
}
}
}
}

插入排序

  • 将第n个数插入前n-1个有序的数组中
1
2
3
4
5
6
7
function insertionSort(arr) {
for (let i = 1; i < arr.length; i++) {
for (let j = i; (arr[j] < arr[j - 1]) && (j >= 0); j--) {
[arr[j - 1], arr[j]] = [arr[j], arr[j-1]];
}
}
}

归并排序

  • 将数组递不断拆分,最后合两个有序数组为一个
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function Merge(arr1, arr2) {
let arr = [];
while(arr1.length || arr2.length) {
if (arr1[0] < arr2[0]) {
arr.push(arr1.shift());
} else {
arr.push(arr2.shift());
}
}
return arr;
}

function mergeSort(arr) {
if (arr.length == 1) {
return arr
}
return Merge(mergeSort(arr.slice(0, Math.floor(arr.length / 2))), mergeSort(arr.slice(Math.floor(arr.length / 2), arr.length)));
}

桶排序

将数组放到n个桶中,确保后面的桶中的元素比前面大,进行排序,然后合并

1
2
3
4
5
6
7
8
9
10
11
function bucketSort(arr) {
let buckets = [[], [], []];
perBucket = Math.floor((Math.max(...arr) - Math.min(...arr) + buckets.length) / buckets.length);
arr.forEach(num => {
let idx = Math.floor((num - Math.min(...arr)) / perBucket);
buckets[idx].push(num);
});
buckets.forEach(bucket => selectionSort(bucket));
arr.length = 0;
arr.push(...buckets.flat());
}

计数排序

创建一个从小到大的数组,然后遍历原数组,在对应位置计数+1

1
2
3
4
5
6
7
8
9
10
function countSort(arr) {
let max = Math.max(...arr);
let min = Math.min(...arr);
let tmp = new Array(max - min + 1).fill(0);
arr.forEach(num => tmp[num - min] += 1);
arr.length = 0;
tmp.forEach((count, index) => {
arr.push(...new Array(count).fill(index + min));
})
}

基数排序

变种桶排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function radixSort(arr) {
let base = 1;
let max = Math.max(...arr);
while(base <= max) {
let buckets = [];
for (let i = 0; i < 10; i++) {
buckets.push([]);
}
arr.forEach(num => {
let idx = Math.floor(num / base) % 10;
buckets[idx].push(num);
})
arr.length = 0;
buckets.forEach(bucket => {
arr.push(...bucket);
})
base = base * 10;
}
}

快速排序

1
2
3
4
5
6
7
8
9
10
function quickSort(arr) {
if (arr.length <= 1) {
return arr;
}
let left = [], right = [];
let pivot = arr.splice(0, 1);
arr.forEach(num => num > pivot ? right.push(num) : left.push(num));
return quickSort(left).concat(pivot, quickSort(right));
}

随机快速排序

1
2
3
4
5
6
7
8
9
function randQuickSort(arr) {
if (arr.length <= 1) {
return arr;
}
let left = [], right = [];
let pivot = arr.splice(parseInt(Math.random() * arr.length), 1);
arr.forEach(num => num > pivot ? right.push(num) : left.push(num));
return randQuickSort(left).concat(pivot, randQuickSort(right));
}

希尔排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function shellSort(arr) {
const n = arr.length;
let gap = Math.floor(n / 2);
while (gap > 0) {
// 插入排序,与普通的插入排序的区别就在于步长为 gap
for (let i = gap; i < n; i++) {
// 从 i 开始向前遍历,间隔为 gap
for (let j = i; j >= gap && arr[j - gap] > arr[j]; j -= gap) {
[arr[j - gap], arr[j]] = [arr[j], arr[j - gap]];
}
}
gap = Math.floor(gap / 2);
}
return arr;
}

内积

性质

  • 交换律
    • $\left\langle\alpha,\beta\right\rangle = \left\langle\beta,\alpha\right\rangle$
  • 非负性
    • $\left \langle \alpha,\alpha \right \rangle \ge 0; \left \langle \alpha,\alpha \right \rangle=0\Leftrightarrow \alpha =0$
  • 齐次性
    • $\left \langle \alpha,k\beta \right \rangle = \overline{k}\left \langle\alpha,\beta\right \rangle$
  • 分配律
    • $\langle\alpha+\gamma,\beta\rangle = \langle\alpha,\beta\rangle + \langle\gamma,\beta\rangle$

Jordan标准形

定义

  • 形如下列形式的矩阵称之为n阶Jordan块
    $$
    J_i=\begin{bmatrix} \lambda_i & 1 & & & \\
    & \lambda_i & 1 & & \\
    & & \lambda_i & \ddots & \\
    & & & \ddots & 1 \\
    & & & & \lambda_i
    \end{bmatrix}_{n_i \times n_i}
    $$

  • 形如下列形式的矩阵称之为n阶Jordan型矩阵
    $$
    J=\begin{bmatrix}
    J_1 & & & \\
    & J_2 & & \\
    & & \ddots & \\
    & & & J_t
    \end{bmatrix}
    $$

    • 其中$J_i$为$n_i$阶Jordan块,且$n_1+\cdots+n_t=n$

定理

  • 每一个n阶复方阵𝑨都和一个Jordan型矩阵𝑱相似。即存在可逆阵𝑷, 使$P^{-1}AP = J$
    • 计算方法:$A \rightarrow A(\lambda)=\lambda E - A \rightarrow 行列式因子 \rightarrow 不变因子 \rightarrow 初级因子 \rightarrow Jordan块 \rightarrow J$
    • 示例:求矩阵$A=\begin{bmatrix}-1&-2&6\\-1&0&3\\-1&-1&4\end{bmatrix}$的Jordan标准型
      • step1: 特征矩阵$A(\lambda)=\lambda E-A=\begin{bmatrix}\lambda+1&2&-6\\1&\lambda&-3\\1&1&\lambda-4\end{bmatrix}$
      • step2: 求行列式因子,$A(\lambda)$中所有k阶子式首项系数是1的最大公因式称为k级行列式因子,记作$D_k(\lambda), k=1,\cdots,n.$
        • 上述$A(\lambda)$,一阶子式为各个元素,$D_1(\lambda)=1$;
        • 二阶子式中,取第一二行、一二列的$\begin{vmatrix}\lambda+1&2\\1&\lambda\end{vmatrix}=\lambda^2+\lambda-2=(\lambda+2)(\lambda-1)$;第一二行、二三列的$\begin{vmatrix}2&-6\\\lambda&-3\end{vmatrix}=-6+6\lambda=6(\lambda-1)$,依次计算,可得$D_2(\lambda)=\lambda-1$;
        • 三阶子式$D_3(\lambda)=(\lambda+1)\lambda(\lambda-4)-6-6+3(\lambda+1)-2(\lambda-4)+6\lambda={(\lambda-1)}^3$
      • step3: 求不变因子:即$d_1(\lambda)=D_1(\lambda),d_n(\lambda)=\frac{D_n(\lambda)}{D_{n-1}(\lambda)}$
        • $d_1=1,d_2=\lambda-1,d_3=(\lambda-1)^2$
      • step4: 将𝑨(𝝀)的所有的次数大于零的不变因子分解为互不相同的一次因式的方幂的乘积,这些一次因式方幂称为𝑨(𝝀)的初级因子。来自于不同的不变因子的一次因子的方幂不能合并
        • $d_1$次数为0,没有初级因子,$d_2$只有一个一次因式$\lambda-1$为其初等因子,$d_3$只有一个一次因式的二次方幂${\lambda-1}^2$为其初等因子
      • step5: 初级因子和Jordan块对应
        • $\lambda-1 \leftrightarrow [1], (\lambda-1)^2 \leftrightarrow \begin{bmatrix}1&1\\0&1\end{bmatrix}$
      • step6: Jordan块按对角线排列起来得到Jordan标准型J,Jordan标准形与Jordan块的顺序无关
        • $J=\begin{bmatrix}1&0&0\\0&1&1\\0&0&1\end{bmatrix}$

$\lambda$-矩阵

定义

  • 位置元$a_{ij}(\lambda)$为多项式的矩阵
  • 𝝀-矩阵的运算,行列式,子式,余子式,伴随矩阵等概念和数字矩阵一致
  • 𝝀-矩阵𝑨(𝝀)的不恒为零多项式的子式的最高阶数称为𝑨(𝝀)的秩(rank), 记为rank𝑨(𝝀)
    • 设𝑨为n阶数字矩阵, 其特征矩阵𝑨(𝝀)=𝝀𝑬−𝑨为𝝀-矩阵,且$rankA(\lambda) = n$

Smith标准型

定理

  • $\lambda$-矩阵都可经若干次初等变换化为Smith标准形,即若$A(\lambda)$为秩为$r$的$m\times n$的$\lambda$-矩阵,则$A(\lambda)$与矩阵$J(\lambda)=\begin{bmatrix}d_1(\lambda)& & &0&\cdots&0\\
    \ &\ddots & &\vdots & &\vdots\\
    \ &\ &d_r(\lambda) &0 &\cdots &0 \\
    0 &\cdots &0 &0 &\cdots &0 \\
    \vdots & &\vdots &\vdots & &\vdots \\
    0 &\cdots &0 &0 &\cdots &0
    \end{bmatrix}$等价。矩阵$J(\lambda)$称之为$A(\lambda)$的Smith标准形.

视口

  • 视口就是浏览器显示页面内容的屏幕区域
  • 视口分为布局视口、视觉视口和理想视口
  • 我们移动端布局想要的是理想视口就是手机屏幕有多宽,我们的布局视口就有多宽
  • 想要理想视口,我们需要给我们的移动端页面添加meta视口标签

meta视口标签

<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

属性 解释
width viewport宽度,可以设置device-width等特殊值
initial-scale 初始缩放比
maximum-scale 最大缩放比
minimum-scale 最小缩放比
user-scalable 用户是否可缩放,yes no

像素

  • 物理像素:屏幕的最小单位。屏幕上用于显示颜色的“点”
  • 逻辑像素:计算机系统中用到的坐标,CSS中的px。逻辑像素的标准控制了在不同设备上的1px有相似的长度。譬如WPF中1px等于1/96英寸,而安卓端1px等于1/160英寸。
  • DPR:设备像素比,CSS中的1px最终会渲染成多少屏幕上的物理像素。

两倍图

  在电脑端1px等于1物理像素,即dpr=1;在手机端通常为了更细腻的显示效果,1px会渲染成多个物理像素。对于一张指定px大小的图片,在手机端会按照DPR放大造成模糊。因此,我们需要在移动端设备上使用二倍图。

CSS属性:background-size

可选参数:

  • cover:拉伸至完全覆盖区域
  • contain:高度宽度等比例拉伸,当宽度、高度等于盒子的宽度、高度时不再拉伸了
  • 百分比,以父盒子的百分比来缩放
  • 只填入一个值一定是宽度,高度值省略,按照等比例缩放。

移动端开发选择

  • 单独制作移动端页面
    • 通过判断设备,如果是移动端设备打开,就跳转到移动端界面
  • 响应式兼容PC移动端
    • 通过判断页面宽度去决定布局
    • 缺点:兼容性问题

移动端技术解决方案

  • CSS初始化 normalize.css
  • 特殊样式
    • -webkit-tap-highlight-color: transparent 去除点击高亮
    • -webkit-apperance: none 按钮和输入框的自定义样式
    • -webkit-touch-callout: none禁用长按页面时的弹出菜单

流式布局(百分比布局)

  • 通过盒子的宽度设置成百分比来根据屏幕的宽度伸缩,不受固定像素的限制,内容向两侧填充
  • 是移动端web开发比较常见的布局方式
  • 用max/min-width/hight确保盒子伸缩在合理范围内。

flex布局

  flex是flexible box的缩写,意为弹性布局,用来为盒装模型最大的灵活性,任何一个容易都可以指定为flex布局。display: flex

  • 当我们为父盒子设置为flex布局以后,子元素的float、clear和vertical-align属性将失效
  • 采用flex布局的元素,称为Flex容器(flex container)简称为容器,他得所有子容器成员,称为flex项目(flex item),简称为“项目”

常见父项属性

  • flex-direction
    • 设置主轴方向,默认的主轴方向就是x轴方向,默认侧轴方向就是y轴方向
    • 属性值:row(默认)、row-reverse(从右到左)、column(从上到下)、column-reverse(从下到上)
  • justify-content
    • 定义了项目在主轴上的对齐方式
    • 属性值:flex-start(从头开始)、flex-end(从尾部开始)、center(在主轴居中对齐)、space-around(平分剩余空间)、space-between(先两边贴边,再平分剩余空间)
  • flex-wrap
    • 默认情况下,flex布局不换行
    • 属性值:no-warp(不换行)、wrap(换行)
  • align-content(换行)
    • 控制子项在侧轴上的对齐方式,单行下没有效果
    • 属性值:参见justify-content
  • align-items(单行)
    • 控制子项在侧轴上的对齐方式
    • 属性值:参见justify-content
  • flex-flow
    • flex-direction和flex-wrap的复合写法

常见子项属性

  • flex
    • 分配子项目的剩余空间,表示子项占多少份数
    • 属性值:数字(默认为0)
  • align-self
    • 单独控制某个项目沿侧轴上的对齐方式
  • order
    • 定义项目的排列顺序
    • 属性值:数字(默认为0),越小越靠前

rem适配布局

  • rem是一个相对单位,类似于em,em是父元素字体大小,rem(root em)是相对于html元素的字体大小。

媒体查询(Media Query)

  • 使用@media查询,可以针对不同的媒体类型定义不同的样式
  • @media可以针对不用屏幕尺寸设置不同的样式
  • 重置浏览器大小,页面也会根据浏览器宽度和高度重新渲染

语法

  • @media mediatype and|not|only (media feature) { css code }
  • mediatype: all / print / screen
  • media feature: max-width / min-width / width

   媒体查询 + rem 能实现元素大小的动态变化。

引入不同的css文件

  • <link rel="stylesheet"media="mediatype and|not|only (media feature)" href="style.css">

Less

  • 变量
    • @变量名: 值
  • Less嵌套
    • 直接放在父元素样式的{}中
    • 伪类、伪元素、交集选择器,在前面加&符号
  • 可进行算数运算
    • 单位不同以第一个为准

Flexible.js

  阿里的一款适配移动端的js开发框架,用于配合rem布局,在不同的页面宽度下,为html元素根节点赋予不同的font-size(默认为页面宽度的1/10),从而控制了元素的相对大小不发生改变。

响应式开发

  使用媒体查询针对不同宽度的设备进行布局和样式,从而适配不同的设备。

设备划分 尺寸区间 宽度设置
手机 <768px 100%
平板 >=768px <992px 750px
桌面显示器 >=992px <1200px 970px
大桌面显示器 >=1200px 1170px

响应式布局容器

  响应式需要一个父级做为布局容器,来配合子级元素来实现变化效果。
  原理就是在不同屏幕下,通过媒体查询来改变这个布局容器的大小,再改变里面子元素的排列方式和大小,从而实现不同屏幕下,看到不同的页面布局和样式变化。

JS移动端特效

touch触摸

  • 触摸事件
    • touchstart 触摸
    • touchmove 按住不动滑动
    • touchend 结束触摸
  • 事件对象
    • touches 触摸屏幕的所有触点的列表
    • targetTouches 触摸当前元素的所有触点的列表
    • changedTouches 触点发生了改变状态的列表

移动端click事件的300ms延迟

  原因:部分浏览器在第一次点击之后会等待300ms判断用户是否是双击(以执行页面放大的行为)
  解决:1. user-scalable设置为no 2.css属性touch-action设置为manipulation(https://developer.mozilla.org/zh-CN/docs/Web/CSS/touch-action)

这篇文章仍处在更新当中。

SEO优化

  对于一个营利性网站而言,提升其在搜索引擎中的排名至关重要。除去直接付费的竞价排名外,搜索引擎优化(Search Engine Optimization)也是不可或缺的一环。

TDK三大标签

  • <title>标签,网站标题:内页的第一个重要标签
    • 建议:网站名 - 网站的介绍(不超过30汉字)
  • description 网站说明
    • 简要说明网站是做什么的
  • keywords 关键字
    • keywords是页面关键词,是搜索引擎的关注点之一
    • 最好限制为6 ~ 8个关键词,且之间用英文逗号隔开
品优购网站的三大标签
1
2
3
4
<title>品优购商城 - 网络购物最佳选择,物美价廉,免费配送,一站式服务为您提供优秀购物体验!</title>
<meta name="description"
content="品优购商城 - 专业的综合网上购物商城,销售家电、数码通讯、电脑、家居百货、服装服饰、母婴、图书、食品等数万个品牌优质商品。便捷、诚信的服务,为您提供愉悦的网上购物体验!" />
<meta name="keywords" content="前端, HTML, CSS, 电商, 品优购商城, 静态界面">

Logo优化

  • logo里面首先放一个<h1>标签(用于提权
  • <h1>标签中插入链接<a>标签,返回首页
  • 链接里面放文字(网站名称),但是为了视觉效果,文字不能显示出来(font-size: 0
  • 链接给一个title属性,鼠标放在Logo上可显示文字
阅读全文 »

这篇文章仍处在更新当中。

HTML

HTML5新增

  • 语义化标签
    • <header> 头部标签
    • <nav> 导航标签
    • <article> 内容标签
    • <section> 定义文档某个区域
    • <aside> 侧边栏
    • <footer> 尾部标签
  • 音频 视频标签
  • input表单类型(见下面)
新增input表单类型 / 属性
  • 邮箱:
  • 网址:
  • 时间:
  • 日期:
  • 数量:
  • 手机号码:
  • 搜索:
  • 颜色:
  • 多选文件:
    • 表单属性(见上面)
      • required 不能为空
      • placeholder 占位提示文本 默认灰色,使用伪类选择器input::placeholder选择 值:对应文本
      • autofocus 自动获得焦点
      • autocomplete 自动补全 值: on / off
      • multiple 多选文件提交

    • 自定义属性
      • H5规定自定义属性data-开头作为属性名并赋值:比如<div data-index='1'></div>
      • 获取属性element.dataset.index或者element.dataset['index']
    阅读全文 »

    这篇文章仍处在更新当中。

    JS基础

    类型

    • 基础数据类型
      最新的 ECMAScript 标准定义了 8 种数据类型,分别是
      • string
      • number
      • bigint
      • boolean
      • null (typeof null返回结果为object)
      • undefined
      • symbol (ECMAScript 2016新增)

    所有基本类型的值都是不可改变的。但需要注意的是,基本类型本身和一个赋值为基本类型的变量的区别。变量会被赋予一个新值,而原值不能像数组、对象以及函数那样被改变。

    • 引用类型
      • Object(包含普通对象-Object,数组对象-Array,正则对象-RegExp,日期对象-Date,数学函数-Math,函数对象-Function)

    基本数据类型会放在上,引用类型放在

    阅读全文 »

    这篇文章仍处在更新当中。

    基础

    只出现一次的数字 / 丢失的数字 / 0 ~ n-1中缺失的数字

    简述:
      ①给定一个包含 [0, n] 中 n 个数的数组 nums,找出 [0, n] 这个范围内没有出现在数组中的那个数。(缺失的数字)
      ②给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。(只出现一次的数字)
    思路:
      一个数字与它自身异或的结果为0,譬如3(011) ^ 3(011) = 0(000),而0与任何数字异或的结果均为其自身。对于②而言,遍历数组,所有数字按位异或即可得到只出现过一次的数字。
      而对于①来说,考虑一个长度为 2n+1 的数组,其中包含了一个nums数组(长度为n),另一部分则是 [0, n] 这 n+1 个数。很显然该数组中只有nums数组缺失的那一个数只出现过一次,剩余数字均出现过两次,因此此题可以转化为 只出现一次的数字 的做法。

    阅读全文 »

      论文标题:Coordinate Attention for Efficient Mobile Network Design

      Github链接

    摘要(翻译)

      近年来对轻量级网络(mobile network)设计的研究表明,通道注意力机制(例如:Squeeze-and-Excitation attention, 压缩-激发注意力机制,出自SENet, CVPR2018)对于模型性能的提升具有显著效果,但它们通常忽略掉了位置信息——这对于生成空间选择性注意力图(spatially selective attention maps)非常重要。在这篇文章中,我们针对轻量级网络提出了一种新的注意力机制,该机制将位置信息嵌入到通道注意力中。我们称其为 坐标注意力(Coordinate Attention) 机制。
      不同于通道注意力将一个特征张量通过二维全局池化转换为单个特征向量,坐标注意力将通道注意力拆解为两个一维特征提取的过程,分别沿着两个空间方向(译注:宽,高)提取特征。通过这种方法可以提取一个空间方向上的远距离依赖关系,同时又可以在另一个空间方向上保持精确的位置信息。结果产生的特征图然后分别编码为一对方向感知(direction-aware)与位置敏感(position-sensitive)的注意力图,可以增补应用于输入的特征图来增强对感兴趣对象的表示。
      我们的坐标注意力机制简单,可以灵活插入于经典的轻量级网络,如MobileNetV2, MobileNeXtEfficientNet并且几乎没有额外的计算开销。大量实验表明,我们的坐标注意力机制在ImageNet分类上存在性能提升,更有趣的是,它在下游任务中表现更好,如目标检测和语义分割。

    阅读全文 »

    2022 / 10 / 19 说明:本文仍为未完成状态,且后续很长一段时间内将不会进一步完善此文。请谨慎阅读这篇文章。

      一般而言,我的需求大多来自实验室,这次也不例外。由于实验室经常承接某些外包的横向项目,因此实验室需要一个能对项目软件进行加密注册的功能以期实现售卖激活码的方式收费盈利。实验室里之前本来就有这玩意儿,但其由C++实现得即为复杂,加之多年来删改维护,让我第一次直观体会到了“屎山”的威力。于是我觉得还不如自己写个Python的Demo玩玩,所谓“功在当代,利在千秋”是也。

      GitHub项目地址:https://github.com/zhmou/RegisterDemo

    阅读全文 »
    0%