位运算经典算法(Swift)

两个数的交换

在这里插入图片描述

无符号整数二进制中1的个数

第一种解法:
循环遍历无符号整数二进制的每一位判断是否为1。
如果二进制中有较多的0,每次右移一位做出判断会很浪费

func countOfOnes(num: UInt) -> UInt {
    var count: UInt = 0
    var temp = num
    while temp != 0 {
        count += temp & 1
        temp = temp >> 1
    }
    return count
}

第二种解法:
使用技巧num = num & (num - 1)消去二进制中最低位的1。
如果最低位为1,num-1后相应位为0,相与之后为0;如果最低位为0,num-1向前借1,有1位则变为0,相与之后为0,则消去了最低位的1。
统计消去次数,便是二进制1的个数

func countOfOnes(num: UInt) -> UInt {
    var count: UInt = 0
    var temp = num
    while (temp != 0) {
        count = count + 1
        temp = temp & (temp - 1)
    }
    return count
}

引申:如何判断一个整数为2的整数次幂

一个整数如果是2的整数次方,那么它的二进制表示中有且只有一位是1,而其他位都是0,如果使用num = num & (num - 1)消去最低位1后,num为0。即判断是否为0,即可判断是否为2的整数次幂。

func isPowerOfTwo(num: UInt) -> Bool {
    return (num & (num - 1) == 0)
}

缺失的数字1

在这里插入图片描述
技巧:
0异或任何数为0,一个数异或自己为0
解法:
数组中的数成对出现,缺失一个数,将所有数异或起来便剩下缺失的数(其他所有成对的数异或为0)

func findLostNum(nums: [UInt]) -> UInt {
    var lostNum: UInt = 0
    for num in nums {
        lostNum = lostNum ^ num
    }
    return lostNum
}

缺失的数字2

在这里插入图片描述
在这里插入图片描述

func findTwoLostNum(nums: [UInt]) -> (UInt, UInt) {
    var lostNum1: UInt = 0
    var lostNum2: UInt = 0
    var temp: UInt = 0
    //两个缺失数的异或
    for num in nums {
        temp = temp ^ num
    }
    var flag: UInt = 1
    //将temp分为temp和flag的异或
    while ((temp & flag) == 0) {
        flag = flag << 1
    }
    //对nums进行分组
    for num in nums {
        if flag & num == 0 {
            lostNum1 = lostNum1 ^ num
        } else {
            lostNum2 = lostNum2 ^ num
        }
    }
    return (lostNum1, lostNum2)
}
发布了51 篇原创文章 · 获赞 19 · 访问量 8283

猜你喜欢

转载自blog.csdn.net/WxqHUT/article/details/103315790