local bit = require("bit")
local bnot = bit.bnot
local band, bor, bxor = bit.band, bit.bor, bit.bxor
local lshift, rshift, rol = bit.lshift, bit.rshift, bit.rol
function missingNumber(nums)
-- 方法一:
-- 1,先拿 x 与 0~n 的数字做 按位异或 运算
local x = 0
for i = 0, #nums do
x = bit.bxor(x, i)
end
-- 2,再拿上一步的 x 与给定数组的元素一一做 按位异或 运算
for k,v in ipairs(nums) do
x = bit.bxor(x, v)
end
-- 方法二:
-- 由于 bxor() 支持多个参数,可以将以上两步合并成下面的一个循环
-- for k, v in ipairs(nums) do
-- x = bit.bxor(x, k, v)
-- end
print("The missing number is: " .. x)
end
-- 实际调用
local nums = {0, 1, 2, 3, 5}
missingNumber(nums)
function isPowerOfTwo(num)
-- 首先判断 num 是否为负数
if num < 0 then
print('这个数是负数,不是 2 的幂。')
return false
end
local hasOne = false
while num > 0 do
-- 判断这个数和 1 做 与运算的结果是否不为 0
if band(num, 1) ~= 0 then -- 注意这里的条件写法
if hasOne then -- 判断 hasOne 是否为 ture
return false -- 如果是 ture,则说明该数字的二进制形式里 1 的数目多于 1 个
else
hasOne = true
end
end
print('移位前: ' .. num)
num = rshift(num, 1) -- 将这个数字右移一位
print('移位后: ' .. num)
print(hasOne)
end
return hasOne;
end
local num = 8
local result = isPowerOfTwo(num)
-- 输出结果:
if result == true then
print('这个数 '.. num ..',是 2 的幂。')
else
print('这个数'.. num ..',不是 2 的幂。')
end
(3) 解法一: 如果最低位为 1 的话,把计算变量加一,然后把 num 向右移动一位,重复上述操作。 当 num 变为 0 时,终止算法,输出结果。
(4) 复杂度:
时间复杂度:O(log2v),log2v 为二进制数的位数,空间复杂度:O(1)。
numberOf1Bits-1.lua 文件:
function numberOf1Bits-1(num)
local count = 0
while num > 0 do
count = count + band(num, 1)
num = rshift(num, 1)
end
return count
end
-- 测试
local num = 7
local result = numberOf1Bits-1(num)
-- 输出结果
print(result) --> 3
(5) 解法二: n & (n - 1) 可以消除最后一个 1,所以用一个循环不停地消除 1 同时计数,直到 n 变成 0 为止。
(6) 复杂度:
时间复杂度:O(m),m 为数字 num 的二进制表示形式中 1 的个数,空间复杂度:O(1)。
numberOf1Bits-2.lua 文件:
function numberOf1Bits-2(num)
local count = 0
while num ~= 0 do
num = band(num, num - 1)
count = count + 1
end
return count
end
-- 测试
local num = 7
local result = numberOf1Bits-2(num)
-- 输出结果
print(result) --> 3
示例 4:Eratosthenes 筛法(素数筛)的一个实现
该算法可以计算出 [1, N] 区间内素数的个数。
local bit = require("bit")
local band, bxor = bit.band, bit.bxor
local rshift, rol = bit.rshift, bit.rol
local m = tonumber(arg and arg[1]) or 100000
if m < 2 then
m = 2
end
local count = 0
local p = {}
for i = 0, (m+31)/32 do
p[i] = -1
end
for i = 2, m do
if band(rshift(p[rshift(i, 5)], i), 1) ~= 0 then
count = count + 1
for j = i+i, m, i do
local jx = rshift(j, 5)
p[jx] = band(p[jx], rol(-2, j))
end
end
end
io.write(string.format("从 1 到 %d,共有 %d 个素数,\n", m, count))