算法练习- 二进制相关

文章目录

二进制概念

  • 二进制是用0、1表示的数,计算各种数据在内存中都是0和1组成;
  • 一个0 或者 1 表示一位(bit),8bits 为一个字节(byte),内存中最小的存储单元为字节;
  • c/c++的int类型一般占用4bytes内存,即4*8=32bits;
  • 对于有符号(正、负)的整数,二进制的最高位表示符号位,0表示正数,1表示负数,如:
    • 32, 二进制结果->00100000
    • -5,二进制结果->10000101
    • 65535, 二进制结果->000000001111111111111111

十进制转为二进制

  • 使用栈结构,整数除2取余数,倒排列;余数入栈; 最后出栈;
  • 也可使用python的bin方法,该方法转出的二进制不是真正的二进制,仍需稍做处理;如bin(30) -> '0b11110';
python 复制代码
import math


def int_to_bin(data: int)-> str:
    """
    :param data: int
    :return: 二进制字符串

    使用栈 结构  实现进制的转换 (按照最小存储空间)
    """
    if data == 0:
        return "0" * 8

    # 符号位
    symbol_pos = "0" if data >=0 else "1"

    # 数据部分的位数
    data_bits = math.ceil(math.log2(abs(data)))
    total_bits = data_bits + 1  # 数据位 + 符号位

    # 总的字节数 (内存中以字节为最小单位)
    total_bytes = math.ceil(total_bits / 8)

    # 创建一个栈
    temp_stack = []
    temp = abs(data)
    # 整数 除2取余 倒排列   余数入栈
    while temp:
        val = temp % 2
        temp_stack.append(val)
        temp = temp // 2

    # 出栈
    result = ""
    while temp_stack:
        result += str(temp_stack.pop())
    print("二进制的数据位:", result)

    # 补0
    complement_zero = "0" * (total_bytes * 8 - data_bits - 1)
    # 符号位 + 补0位 + 数据位
    bin_data = symbol_pos + complement_zero + result
    return bin_data


if __name__ == '__main__':
    bin_val = int_to_bin(65535)
    print("二进制结果:", bin_val)

二进制转为十进制

思路:加权求和,转为十进制

如00011110 转为十进制 -> 1 ∗ 2 4 + 1 ∗ 2 3 + 1 ∗ 2 2 + 1 ∗ 2 1 + 0 ∗ 2 0 = 30 {1*2^4 + 1*2^3 + 1* 2^2+1*2^1 + 0*2^0}=30 1∗24+1∗23+1∗22+1∗21+0∗20=30

python 复制代码
# 输入一个二进制字符串,返回整数
def bin_to_int(data: str) -> int:
    # 符号位
    symbol = 1 if data[0] == "0" else -1
    # 数据位
    data_part = data[1:]
    base = len(data_part) - 1
    result = 0
    for i in data_part:
        if i == "1":
            result += 1 * 2 ** base
        base -= 1

    return symbol * result

案例练习

  • 将一个无符号(只有非负)整数,转为二进制;
  • 翻转该二进制结果,即低八位转为高八位,次低八位转为次高八位,依次类推;
  • 将翻转后的二进制,转为十六进制;
    • 四位二进制对应一位十六进制;
    • 十六进制字符 0-9,A/B/C/D/E/F;
    • 如65535转为二进制 000000001111111111111111,翻转后111111111111111100000000,转为十六进制为FFFF00,这里的八位0可以不用,只是用来区分翻转的效果。
python 复制代码
import math


def int_to_bin(data: int)-> str:
    """
    :param data: 无符号整型,即非负整数
    :return: 二进制字符串,没有符号位,只有数据位

    这里使用python内置函数bin实现进制的转换 (按照最小存储空间)
    """
    if data == 0:
        return "0" * 8

    # 数据部分的位数
    data_bits = math.ceil(math.log2(data))

    # 总的字节数 (内存中以字节为最小单位)
    total_bytes = math.ceil(data_bits / 8)

    # bin转换二进制
    bin_data = bin(data)  # 0b0011 形式
    # 分割二进制数据
    bin_data_part = bin_data[2:]

    # 补0
    complement_zero = "0" * (total_bytes * 8 - data_bits)
    # 补0位 + 数据位
    bin_data = complement_zero + bin_data_part

    # 此时所有位均表示数据
    return bin_data


def bin_to_int(data: str) -> int:
    # (无符号)二进制中每一位均表示数据
    base = len(data) - 1
    result = 0
    for i in data:
        if i == "1":
            result += 1 * 2 ** base
        base -= 1

    # 得到非负数
    return result


def reverse_bin_str(data: str) -> str:
    """
    :param data:  传入一个二进制字符串
    :return: 翻转后的二进制字符串
    """
    n = len(data)
    result = ""
    interval = 8
    for i in range(0, n, interval):
        result = data[i:i+interval] + result

    return result


def bin_to_hex(data: str)-> str:
    """
    :param data: 二进制字符串
    :return: 十六进制字符串
    """
    n = len(data)
    interval = 4
    region_val = 9
    result = ""
    for i in range(0, n, interval):
        decimal_val = bin_to_int(data[i:i+interval])
        hex_char = str(decimal_val) if decimal_val <= region_val else chr(decimal_val % region_val + 64) # A-65 F-70
        result += hex_char

    return result


if __name__ == '__main__':
    bin_val = int_to_bin(65567)  # 1F0001
    print("二进制结果:", bin_val)
    rev_val = reverse_bin_str(bin_val)
    print("翻转二进制:", rev_val)

    hex_val = bin_to_hex(rev_val)
    print("十六进制:", hex_val)
相关推荐
_WndProc5 分钟前
C++ 日志输出
开发语言·c++·算法
努力学习编程的伍大侠18 分钟前
基础排序算法
数据结构·c++·算法
XiaoLeisj1 小时前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
Jasmine_llq1 小时前
《 火星人 》
算法·青少年编程·c#
闻缺陷则喜何志丹1 小时前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径
Lenyiin2 小时前
01.02、判定是否互为字符重排
算法·leetcode
鸽鸽程序猿2 小时前
【算法】【优选算法】宽搜(BFS)中队列的使用
算法·宽度优先·队列
Jackey_Song_Odd2 小时前
C语言 单向链表反转问题
c语言·数据结构·算法·链表
Watermelo6172 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript