首页

▼ 算法合集

▼ 加密算法

▼ 凯撒密码

凯撒密码

▼ Hill密码算法

Hill密码算法

▼ 多项式哈希算法

多项式哈希算法

▼ Rail Fence Cipher

Rail Fence Cipher

▼ Graph算法

▼ 关节点

关节点

▼ Bellman-Ford算法

Bellman-Ford算法

▼ 广度优先搜索

广度优先搜索

▼ GraphBridges

桥接模式

▼ 深度优先搜索

深度优先搜索

▼ 检测循环

检测循环

▼ Dijkstra算法

Dijkstra算法

▼ Eulerian Path

欧拉路径

▼ Floyd-Warshall算法

Floyd-Warshall算法

▼ HamiltonianCycle

Hamiltonian Cycle

▼ Kruskal算法

Kruskal算法

▼ Prim算法

Prim算法

▼ 强连通分量

强连通分量

▼ 拓扑排序

拓扑排序

▼ Travelling Salesman Problem

Travelling Salesman

▼ 图像处理算法

▼ Seam Carving算法

内容感知缩放算法

▼ 链表

▼ 反向遍历

反向遍历

▼ GraphTraversal

GraphTraversal

▼ 数学算法

▼ 二进制浮点数

BinaryFloatingPoint

▼ 位操作

位操作算法

▼ 复数

复数

▼ 欧几里得算法

Euclidean Algorithm

▼ Euclidean Distance

欧几里得距离

▼ 阶乘算法

阶乘算法

▼ 快速幂算法

快速幂算法

▼ Fibonacci数列

斐波那契数列

▼ 傅里叶变换

Fourier变换

▼ Horner法

霍纳法则

▼ 整数划分

整数划分

▼ 判断是否为2的幂

判断是否为2的幂

▼ 最小公倍数

最小公倍数

▼ Liu Hui

Liu Hui

▼ 矩阵

Matrix

▼ Pascal三角形

Pascal三角形

▼ Primality Test

素数测试

▼ 质因数

质因数

▼ 弧度计算

弧度计算

▼ 埃拉托色尼筛法

埃拉托色尼筛法

▼ SquareRoot

SquareRoot

▼ MachineLearning

▼ K均值算法

K均值算法

▼ K近邻算法

K近邻算法

▼ 搜索算法

▼ 二分查找算法

二分查找

▼ 插值搜索算法

插值搜索算法

▼ 跳跃搜索算法

跳跃搜索算法

▼ 线性搜索

线性搜索算法

▼ 集合

▼ 笛卡尔积

笛卡尔积

▼ 组合总和

组合总和

▼ 组合算法

组合算法

▼ Fisher-Yates洗牌算法

Fisher-Yates洗牌算法

▼ 背包问题

背包问题

▼ 最长公共子序列

最长公共子序列

▼ 最长递增子序列

最长递增子序列

▼ 最大子数组

最大子数组

▼ 排列组合

排列组合

▼ 幂集

幂集算法

▼ 最短公共超序列

最短公共超序列

▼ Sorting Algorithms

▼ 冒泡排序

冒泡排序

▼ 桶排序算法

桶排序算法

▼ 计数排序算法

计数排序

▼ 堆排序算法

堆排序

▼ 插入排序

插入排序

▼ 归并排序

归并排序

▼ 快速排序算法

快速排序算法

▼ 基数排序

基数排序

▼ 选择排序算法

选择排序算法

▼ 希尔排序

希尔排序

▼ 统计学

▼ 加权随机

加权随机算法

▼ 字符串算法

▼ Hamming距离

Hamming距离

▼ KnuthMorrisPratt算法

Knuth-Morris-Pratt算法

▼ LevenshteinDistance

Levenshtein距离

▼ 最长公共子串

最长公共子串

▼ 回文检测算法

回文检测算法

▼ Rabin-Karp算法

Rabin-Karp算法

▼ 正则表达式匹配

正则表达式匹配

▼ Z算法

Z算法

▼ Tree Data Structure

▼ 广度优先搜索

广度优先搜索

▼ 深度优先搜索

深度优先搜索

▼ 未分类

▼ 最佳买卖股票时机

最佳买卖股票时机

▼ 汉诺塔算法

HanoiTower

▼ 跳跃游戏算法

跳跃游戏

▼ KnightTour

骑士巡逻

▼ N皇后问题

N皇后问题

▼ 雨水收集

雨水收集

▼ 递归楼梯问题

递归楼梯问题

▼ 方阵旋转

方阵旋转

▼ 独特路径

UniquePaths

▼ 数据结构

▼ BloomFilter算法

布隆过滤器

▼ 不相交集数据结构

Disjoint Set

▼ 双向链表

双向链表

▼ Graph

Graph算法

▼ 哈希表

哈希表

▼ Heap数据结构

Heap数据结构

▼ 链表

链表

▼ LRU缓存

LRU缓存

▼ 优先队列

优先队列

▼ 队列

队列

▼ 栈结构

栈结构

▼ Tree Data Structure

树结构

▼ AVL树

AVL树

▼ 二叉搜索树

二叉搜索树

▼ Fenwick树

Fenwick树

▼ 红黑树

红黑树

▼ 线段树

SegmentTree

▼ Trie数据结构

Trie数据结构

位运算

Read this in other languages: français, english

Get Bit

该方法向右移动目标位到最右边,即位数组的第0个位置上。然后在该数上与形如 0001的二进制形式的数进行AND操作。这会清理掉除了目标位的所有其它位的数据。如果目标位是1,那么结果就是1,反之,结果是0;

查看getBit.js了解更多细节。

Set Bit

该方法把1向左移动了bitPosition位,生成了一个二进制形如00100的值。然后我们拿该值与目标数字进行OR操作,就能把目标位设置位1而不影响其它位。

查看setBit.js了解更多细节。

Clear Bit

该方法把1向左移动了bitPosition位,生成了一个二进制形如00100的值。然后反转每一位的数字,得到一个二进制形如11011的值。接着与目标值进行AND操作,就能清除掉目标位的值。

查看clearBit.js了解更多细节。

Update Bit

该方法组合了“Clear Bit”和“Set Bit”

查看updateBit.js了解更多细节。

isEven

该方法检测传入的number是否是偶数。它的实现基于奇数的最右边的位永远是1这个事实。

Number: 5 = 0b0101
isEven: false

Number: 4 = 0b0100
isEven: true

查看isEven.js了解更多细节。

isPositive

该方法检测传入的number是否是正数。它的实现基于正数最左边的位永远是0这个事实。然而如果传入的number是0或者-0,它也应该返回false。

Number: 1 = 0b0001
isPositive: true

Number: -1 = -0b0001
isPositive: false

查看isPositive.js了解更多细节。

Multiply By Two

该方法将原始数字向左移动一位。因此所有位都将乘以2,因此数字本身也将乘以2。

Before the shift
Number: 0b0101 = 5
Powers of two: 0 + 2^2 + 0 + 2^0

After the shift
Number: 0b1010 = 10
Powers of two: 2^3 + 0 + 2^1 + 0

查看multiplyByTwo.js了解更多细节。

Divide By Two

该方法将原始数字向右移动一位。因此所有位都将除以2,因此数字本身也将除以2,且不会产生余数。

Before the shift
Number: 0b0101 = 5
Powers of two: 0 + 2^2 + 0 + 2^0

After the shift
Number: 0b0010 = 2
Powers of two: 0 + 0 + 2^1 + 0

查看divideByTwo.js了解更多细节。

Switch Sign

该方法将正数变成负数,反之亦然。为了做到这一点,它使用了“二进制补码”的方法,即取反所有位然后加1.

1101 -3
1110 -2
1111 -1
0000  0
0001  1
0010  2
0011  3

查看switchSign.js了解更多细节。

Multiply Two Signed Numbers

该方法使用位运算符计算两个有符号数的乘积。实现基于以下事实:

a * b 可以被改写成如下形式:
  0                     a为0,b为0,或者a,b都为0
  2a * (b/2)            b是偶数
  2a * (b - 1)/2 + a    b是奇数,正数
  2a * (b + 1)/2 - a    b是奇数,负数

这样转换的优势在于,递归的每一步,递归的操作数的值都减少了一半。因此,运行时的时间复杂度为O(log(b)),其中b是在每个递归步骤上减少为一半的操作数。

查看multiply.js了解更多细节。

Multiply Two Unsigned Numbers

该方法使用位运算符计算两个无符号数的乘积。实现基于“每个数字都可以表示为一系列2的幂的和”。

逐位乘法的主要思想是,每个数字都可以拆分为两个乘方的和:

比如:

19 = 2^4 + 2^1 + 2^0

然后19x就等价于:

x * 19 = x * 2^4 + x * 2^1 + x * 2^0

接着我们应该意识到x*2^4是等价于x向左移动4位(x << 4)的;

查看multiplyUnsigned.js了解更多细节。

Count Set Bits

该方法使用位运算符对一个数字里设置为1的位进行记数。主要方法是,把数字每次向右移动1位,然后使用&操作符取出最右边一位的值,1则记数加1,0则不计。

Number: 5 = 0b0101
Count of set bits = 2

查看countSetBits.js了解更多细节。

Count Bits to Flip One Number to Another

该方法输出把一个数字转换为另一个数字所需要转换的位数。这利用了以下特性:当数字进行XOR异或运算时,结果将是不同位数的数量(即异或的结果中所有被设置为1的位的数量)。

5 = 0b0101
1 = 0b0001
Count of Bits to be Flipped: 1

查看bitsDiff.js了解更多细节。

Count Bits of a Number

为了计算数字的有效位数,我们需要把1每次向左移动一位,然后检查产生的值是否大于输入的数字。

5 = 0b0101
有效位数: 3
当我们把1向左移动4位的时候,会大于5.

查看bitLength.js了解更多细节。

Is Power of Two

该方法检测数字是否可以表示为2的幂。它使用了以下特性,我们定义powerNumber是可以写成2的幂的形式的数(2,4,8,16 etc.)。然后我们会把powerNumberpowerNumber - 1进行&操作,它会返回0(如果该数字可以表示为2的幂)。

Number: 4 = 0b0100
Number: 3 = (4 - 1) = 0b0011
4 & 3 = 0b0100 & 0b0011 = 0b0000 <-- Equal to zero, is power of two.

Number: 10 = 0b01010
Number: 9 = (10 - 1) = 0b01001
10 & 9 = 0b01010 & 0b01001 = 0b01000 <-- Not equal to zero, not a power of two.

查看isPowerOfTwo.js了解更多细节。

Full Adder

该方法使用位运算符计算两个数的和。

它实现了完整的加法器电子电路逻辑,以补码的形式计算两个32位数字的和。它使用布尔逻辑来覆盖了两个位相加的所有情况:从前一位相加的时候,产没产生进位“carry bit”。

Legend:

  • A: 数字 A
  • B: 数字 B
  • ai: 数字A以二进制表示时的位下标
  • bi: 数字B以二进制表示时的位下标
  • carryIn: 本次计算产生的进位
  • carryOut: 带入此次计算的进位
  • bitSum: ai, bi, 和 carryIn 的和
  • resultBin: 当前计算的结果(二进制形式)
  • resultDec: 当前计算的结果(十进制形式)
A = 3: 011
B = 6: 110
┌──────┬────┬────┬─────────┬──────────┬─────────┬───────────┬───────────┐
│  bit │ ai │ bi │ carryIn │ carryOut │  bitSum │ resultBin │ resultDec │
├──────┼────┼────┼─────────┼──────────┼─────────┼───────────┼───────────┤
│   0  │ 1  │ 0  │    0    │    0     │     1   │       1   │     1     │
│   1  │ 1  │ 1  │    0    │    1     │     0   │      01   │     1     │
│   2  │ 0  │ 1  │    1    │    1     │     0   │     001   │     1     │
│   3  │ 0  │ 0  │    1    │    0     │     1   │    1001   │     9     │
└──────┴────┴────┴─────────┴──────────┴─────────┴───────────┴───────────┘

查看fullAdder.js了解更多细节。
查看Full Adder on YouTube.

References