算法回忆录——排序

文章目录

  • 1. 插入排序
  • 2. 选择排序
  • 3. 冒泡排序
  • 4. 希尔排序
  • 5. 归并排序
  • 6. 快速排序
  • 7. 堆排序
  • 8. 计数排序
  • 9. 桶排序
  • 10. 基数排序

1. 插入排序

分为两个序列,前面一个序列是排好序的,后面一个序列是未排好的。未排好的序列的第一个元素(a)从后往前去和排好序的序列的元素(b)挨个比较。若a<b,就需将b往后移一位(需要提前用一个变量存储a的值)。然后继续比较,那么就会有两种情况:1. 比较到a>b时停止,此时a停留的下标就在b的后一个,也就是a要占据的位置。2. 比较到最后也没有比a小的b,此时a就应该占据该有序序列的第一个位置。

a = [21,3,10,33,9,22,34,18,26,15,100,2,11,31,52]


for i in range(1, len(a)):
    # i表示未排好的序列的第一个元素的下标
    # j表示已排好的序列的最后一个元素的下标
    j = i - 1

    # 开始将a[i]与已排好的序列进行比较
    while j >= 0:
        # 如果小于
        if a[i] < a[j]:
            # 下标减一继续往前比较
            j -= 1
        else:
            # 如果a[i] > a[j],则可以终止循环了
            break
    
    # 循环结束时的j表示a[i]>a[j]的那个j,所以a[i]要放入的位置应该在a[j]的后面
    # 或者说循环结束时一直没有找到比a[i]小的a[j],此时j为-1,应当放入最前面
    j += 1

    # 将a[i]存储起来
    b = a[i]
    # 然后将已排好的序列从j的位置开始,整体往后移一位
    for n in range(i, j, -1):
        a[n] = a[n - 1]
    # 最后再在j处放上a[i]
    a[j] = b
    
print(a)

改进:可以不用在找到插入位置的时候再挨个往后移,可以先将a[i]存储起来,在与排好的序列挨个比较时就开始往后移。

a = [21, 3, 10, 33, 9, 22, 34, 18, 26, 15, 100, 2, 11, 31, 100, 52]

for i in range(0, len(a) - 1):
    # 排好序列的最后一个元素的下标
    end = i
    
    # 存储好当前未排元素
    wait = a[end + 1]
    
    # 将该未排元素开始依次从后往前与排好的元素比较
    while end >= 0:
        # 如果该未排元素小于当前已排好的元素,就将当前已排好元素往后移
        if wait < a[end]:
            a[end + 1] = a[end]
            end -= 1
        else:
            break
    
    a[end + 1] = wait

print(a)

2. 选择排序

先找到最小的元素,与原序列第一个元素交换,然后再去排除第一个元素的序列中找到最小的,与原序列中第二个元素交换…

a = [21,3,10,33,9,22,34,18,26,15,100,2,11,31,52]

def select_sort(a, n):
    # 依次从未排序的序列中找到最小的元素的下标
    for i in range(n):
        pos = i
        # 用原序列第一个元素去跟剩下元素比较,找到最小的元素,然后记录下标
        for j in range(i + 1, n):
            if a[j] < a[pos]:
                pos = j
        # 此时已经找到最小元素的下标,与原序列第一个元素交换位置
        a[i], a[pos] = a[pos], a[i]

    return a
print(select_sort(a, len(a)))

3. 冒泡排序

冒泡排序就是将一个数与其它数挨个比较,在比较的过程中,始终是小的数在前面,大的数在后面,这样不断比较和交换,大的数就挨个排到后面去了。

a = [21,3,10,33,9,22,34,18,26,15,100,2,11,31,52]

def bubble_sort(a, n):
    for i in range(n):
        for j in range(n - 1):
            if a[j + 1] < a[j]:
                a[j], a[j + 1] = a[j + 1], a[j]
    return a
print(bubble_sort(a, len(a)))

4. 希尔排序

希尔排序也算是一种插入排序,不过它是按照某种规则进行分组后,在每个组内进行插入排序。

分组主要就是靠**“增量”**来划分。增量的取值又很多种,普遍简单的是以第一个增量为,数组长度的一半(向下取整),第二个增量取第一个增量的一半…最后一个增量一定是1。

那么是如何按照增量分组的呢?

如果以取半的方式来获得增量,那么有增量是多少,就分多少组。

image-20240107163348776

image-20240107163822321

image-20240107164058388

a = [21,3,10,33,9,22,34,18,26,15,100,2,11,31,52]

def hill_sort(a, n):
    # 先取增量为数组长度
    gap = n
    
    # 循环结束的条件,gap=1就是最后一次分组,此时gap/2=0,循环就结束了
    while gap > 0:
        # 每次gap取半
        gap = int(gap / 2)
        # 增量是多少就有几个组,所以我们需要对每个组进行插入排序
        for i in range(0, gap):
            # 对其中一组进行插入排序
            for j in range(i, n, gap):
                end = j
                # 这里需要判断下标是否超出了原数组的长度,其它的操作都是和插入排序一样的
                if end + gap >= n:
                    break
                wait = a[end + gap]
                while end >= 0:
                    if wait < a[end]:
                        a[end + gap] = a[end]
                        end -= gap
                    else:
                        break
                a[end + gap] = wait

    return a

print(hill_sort(a, len(a)))

下面的代码少了一个循环,就是单独都每个组进行插入排序的那个循环。

a = [21,3,10,33,9,22,34,18,26,15,100,2,11,31,52]

def hill_sort(a, n):
    gap = n
    while gap > 0:
        gap = int(gap / 2)
        for i in range(0, n):
            end = i
            if end + gap >= n:
                continue
            wait = a[end + gap]
            while end >= 0:
                if wait < a[end]:
                    a[end + gap] = a[end]
                    end -= gap
                else:
                    break
            a[end + gap] = wait

    return a

print(hill_sort(a, len(a)))

5. 归并排序

归并排序采用分治策略,即将一个序列拆分成许多小序列进行排序,就是将排好序的小序列合起来再进行排序。

在这里插入图片描述

有两种实现方式:递归和迭代

  • 递归:实现递归的时候不要多想,假设递归一次就成功。
a = [21,3,10,33,9,22,34,18,26,15,100,2,11,31,52]

def merge_sort(a):
    # 数组长度
    n = len(a)
    
    # 递归终止条件。当数组不断被拆分,直至只剩一个元素时,递归就终止,开始一层一层地从里往外计算。
    if n <= 1:
        return a
    
    # 向下取整,如果数组是奇数大小,那么左边部分一定比右边部分小1
    mid = int(n / 2)
    
    # 拆分后将左边和右边部分分别进行递归
    # 其实就只有这里需要递归,所以这里写好后就不要去考虑一层一层嵌套的问题了
    left = merge_sort(a[:mid])
    right = merge_sort(a[mid:])
    
    # 用来存放“治”后的数组,也就是将两个数组中的元素按从小到大的顺序依次放入sort中
    sort = []
    
    i, j = len(left), len(right)
    
    # 这里是假设两个数组都有元素的情况,若其中一个数组元素被弹完了,循环终止
    while i and j:
        if left[0] <= right[0]:
            # 将小的一个添加到sort数组中
            sort.append(left[0])
            # 并将这个元素从原数组中弹出
            left.pop(0)
            i -= 1
        else:
            sort.append(right[0])
            right.pop(0)
            j -= 1
    
    # 当上面循环结束后只有两种情况:
    # 1. 两个数组元素都弹完
    # 2. 一个数组弹完,剩下一个数组未弹完
    # 那么我就需要将未弹完元素的数组弹尽,同时挨个添加到sort数组中
    while i:
        sort.append(left[0])
        left.pop(0)
        i -= 1
    while j:
        sort.append(right[0])
        right.pop(0)
        j -= 1
    return sort

print(merge_sort(a))
  • 迭代(不会,2024.1.7)

6. 快速排序

快速排序跟冒泡排序很像,都是通过交换两元素位置来排序的。

快速排序需要一个基准元素(通常取数组的第一个元素)和left、right两个左右指针。它就是通过不断将元素与基准元素比较,比基准元素小就放在它的左边,比基准元素大就放在它的右边,然后再让基准元素左边那一段和右边那一段分别进行递归。

left指针一定指向的是数组的左边界(不一定是0)

right指针一定指向的是数组的有边界(不一定是数组的长度-1)

步骤:

  • 判断递归结束的条件
  • 用i和j来代替left和right,边界是固定的,是为了继续向下递归
  • 定义基准元素
  • 开始执行循环比较:
    • 若右指针指向的元素>=基准元素:右指针左移
    • 若右指针指向的元素<=基准元素:右指针指向的元素和左指针指向的元素交换
    • 若左指针指向的元素<=基准元素:左指针右移
    • 若左指针指向的元素>=基准元素:左指针指向的元素和右指针指向的元素交换
arr = [21,3,10,33,9,22,34,18,26,15,100,2,11,31,52]

def quick_sort(arr, left, right):

    # 递归结束条件
    if left >= right:
        return

    # 用i和j分别作为左、右指针来进行移动过
    # 不能直接用left和right来当作指针,它们是用来当作边界的
    # left用来规定一段递归的起点,right用来规定另一段递归的终点
    i = left
    j = right
    # 基准数
    base = arr[i]

    # 当左指针始终小于右指针的时候,不断地移动指针和交换指针所指向的元素
    while i < j:

        # 如果右指针指向的元素>基准数,右指针左移
        while i < j and arr[j] >= base:
            j -= 1
        # 当上面循环结束时,表示右指针指向的元素小于基准数,将右指针指向的元素与左指针指向的元素交换(只是元素交换位置)
        arr[j], arr[i] = arr[i], arr[j]

        # 如果左指针指向的元素<基准数,左指针右移
        while i < j and arr[i] <= base:
            i += 1
        # 当上面循环结束时,表示左指针指向的元素大于基准数,将左指针指向的元素与右指针指向的元素交换
        arr[i], arr[j] = arr[j], arr[i]

    # 当上面循环结束后,左指针和右指针一定是相等的
    quick_sort(arr, left, i - 1)
    quick_sort(arr, i + 1, right)

quick_sort(arr, 0, len(arr) - 1)
print(arr)

7. 堆排序

堆排序本质上还是对数组排序,只是将数组中的元素按树结构的方式排序。

堆本质上也是一棵二叉树。分为大顶堆和小顶堆。大顶堆就是每个根节点的值一定大于等于其左右子节点的值,小顶堆类同。

如何将数组排列成一个堆?

  • 将数组元素依次从上到下,从左到右排列

堆排序一共分为两大步:

  • 将数组排列成一个大顶堆,其中每个根节点都应该满足大顶堆的要求
  • 将堆顶元素与堆中最后一个元素交换,然后将最后一个元素排除在堆外,再重新对这个堆进行大顶堆化。直到排除掉最后一个元素为止

避坑:

  • 最后一个非叶子节点一定是处于length / 2 - 1的位置,它前面的节点也一定有子节点
代码参考:
https://www.hello-algo.com/chapter_sorting/heap_sort/#1171
https://zq99299.github.io/dsalg-tutorial/dsalg-java-hsp/11/01.html#%E5%AE%8C%E6%95%B4%E5%AE%9E%E7%8E%B0
arr = [21,3,10,33,9,22,34,18,26,15,100,2,11,31,52]

# 调整堆结构(保持大顶堆)
def adjust_heap(arr, pos, length):
    """

    Args:
        arr: 要调整的堆(数组)
        pos: 调整的起始位置(非叶子节点)
             如果是创建大顶堆,则pos表示的是最下层最右边的那个非叶子节点
        length: 堆的长度
                    - 如果是创建堆,则length不变
                    - 如果是将根节点元素与堆尾元素交换,则每执行一次length-1
    Returns:

    """
    while True:
        # 左子节点的位置
        l = pos * 2 + 1

        # 右子节点的位置
        r = pos * 2 + 2

        # max表示值最大的节点的位置,在调整之前,假定是根节点的位置
        max = pos

        # 如果左子节点的位置(下标)在堆长度范围内且左子节点元素的值大于它的父节点的值
        if l < length and arr[l] > arr[max]:
            # max表示的就是左子节点的位置(值更大元素的位置)
            max = l
        # 如果右子节点的位置在堆长度范围内且右子节点元素的值大于它的父节点的值
        if r < length and arr[r] > arr[max]:
            # max表示的就是右子节点的位置
            max = r

        # 如果左右子节点都不大于根节点,max就表示的是根节点的位置,而pos始终都表示根节点的位置,此时就退出循环
        if max == pos:
            break

        # 如果左右子节点有一个大于根节点,则交换两个元素
        arr[pos], arr[max] = arr[max], arr[pos]

        # 然后又将交换的那个子节点作为根节点,对它下面的堆继续调整
        # 因为如果该子节点也是一个堆,它是堆中最大的元素
        # 但当它的父节点比它小,从而它和父节点交换,此时它的值在它的堆中就不一定是最大的
        # 另一个子节点自然不用考虑,它肯定是它堆中最大的
        pos = max



def heap_sort(arr):
    # 将数组创建为一个大顶堆
    for i in range(int(len(arr) / 2) - 1, -1, -1):
        adjust_heap(arr, i, len(arr))

    # 交换堆顶元素与堆最后一个元素,然后将最后一个元素排除堆
    # 将交换后的堆又调整成为一个大顶堆
    for i in range(len(arr) - 1, 0, -1):
        arr[0], arr[i] = arr[i], arr[0]
        adjust_heap(arr, 0, i)

heap_sort(arr)
print(arr)

8. 计数排序

计数排序顾名思义就是通过计算arr数组中元素的出现次数来进行排序。

需要额外一个数组来计算arr数组中元素的出现次数。

计数数组的长度为arr数组中最大值(max)-最小值(min)+1。

计数数组的下标区间:[0, max-min+1),当下标区间都加上一个min后:[min, max+1)

右边是开区间是因为数组长度为max-min+1,而数组的下标是从0开始的。

arr = [21,3,10,33,9,22,34,18,26,15,100,2,11,31,52]

def counting_sort(arr):
    # 先获取数组中的最大值和最小值
    min = arr[0]
    max = arr[0]
    for i in range(1, len(arr)):
        if arr[i] <= min:
            min = arr[i]
        if arr[i] >= max:
            max = arr[i]

    # 计数用的数组,数组的大小为arr中最大值-最小值+1,该数组的下标就用来表示min到max之间的数
    counter = [0] * (max - min + 1)

    # 统计arr数组中每个元素出现的次数
    for i in range(len(arr)):
        # counter的下标相当于在一个区间[0, max-min+1],当它的下标加上一个min就表示[min,max]之间的所有数
        # max-min“+1”是因为下标是从0开始的
        counter[arr[i] - min] += 1

    # n用来表示arr中元素的下标
    n = 0
    for j in range(len(counter)):
        # counter数组中的值,就表示它的下标加上min的值这个数出现的次数
        while counter[j] != 0:
            arr[n] = j + min
            counter[j] -= 1
            n += 1

counting_sort(arr)
print(arr)

9. 桶排序

桶排序就是先确定几个桶,然后将数组中的元素按照某种规则放入桶中,分别对每个桶中的元素进行排序,然后再依次从第一个桶开始将元素拿出来。(后一个桶中的元素的值一定大于前一个桶中元素的值)。

  • 一个桶放几个元素(bucketSize):人为规定或使用默认值
  • 桶数量的确定(bukcetNum):arr数组中的(max - min + 1)/ bucketSize
  • 确定元素放入哪个桶:bucket[(arr[i] - min) / bucketSize]
arr = [21,3,10,33,9,22,34,18,26,15,100,2,11,31,52]

def bucket_sort(arr, bucketSize=5):
    """

    Args:
        arr:
        bucketSize: 每个桶的容量

    Returns:

    """

    # 找出arr数组中最大值和最小值
    max = arr[0]
    min = arr[0]
    for i in range(len(arr)):
        if max < arr[i]:
            max = arr[i]
        if min > arr[i]:
            min = arr[i]

    # 区间【min,max】一共有max-min+1个数,一个桶装bucketSize个数,所以相除就得到了桶的数量
    # 最后再加个1是防止前面被除数小于除数,结果就为0个桶,显然是不行的
    bucketNum = int((max - min + 1) / bucketSize + 1)

    # 初始化桶
    bucket = []
    for j in range(bucketNum):
        bucket.append([])

    # 将arr数组中的元素按照范围放入桶中
    # 可以看到前面桶的数量的定义,要确定放入哪个桶,(arr[i]-min)/bucketSize就能确定桶号
    for k in range(len(arr)):
        bucket[int((arr[k] - min) / bucketSize)].append(arr[k])
    
    # 桶内进行排序,各种排序方式都行
    for i in range(len(bucket)):
        # 这里使用的是前面的快速排序
        quick_sort(bucket[i], 0, len(bucket[i]) - 1)
    
    # 将桶内元素排完序后,从第一个桶开始,依次将桶内元素替换掉arr数组中的元素
    n = 0
    for i in range(len(bucket)):
        if bucket[i]:
            for j in range(len(bucket[i])):
                arr[n] = bucket[i][j]
                n += 1


bucket_sort(arr)
print(arr)

10. 基数排序

基数排序是桶排序的拓展,假如排序的数是十进制的,那么每一个数的每一位有10种表示,那么就创建10个桶。

从个位开始,每个数的个位是多少,就放入哪个桶。全部放完后再从第一个桶开始取出来挨个放入原数组,先放进去的先取。

然后从十位开始…

当排序到最后一轮的时候,再取出来放入原数组,这时原数组就有序了。

arr = [21,3,10,33,9,22,34,18,26,15,100,2,11,31,52]

def radix_sort(arr):
    # 找出arr数组中最大的元素
    max = arr[0]
    for i in range(len(arr)):
        if max < arr[i]:
            max = arr[i]

    # 得到它的位数
    sortNum = len(str(max))


    # 因为是十进制的排序,所以十个桶就行了
    bucketNum = 10

    # 初始化桶
    bucket = []
    for i in range(bucketNum):
        bucket.append([])

    # n是用来辅助求得个位上的数,例如123 / n % 10 = 3      int(123 / (n * 10)) % 10 = 2....
    n = 1

    # 最大元素有几位就要进行几次排序
    for i in range(sortNum):

        # 初始化桶的计数数组,记录每个桶有多少个元素
        counter = [0 for j in range(bucketNum)]

        # 将元素按照它们个位个位、十位等等的数分别放入桶中
        for k in range(len(arr)):
            # 得到个位或十位等等上的数
            d = int(arr[k] / n) % 10
            # 放入相应的桶中
            bucket[d].append(arr[k])
            # 放入一个就加1
            counter[d] += 1

        # 指示arr数组元素的位置
        index = 0
        # 开始依次将每个桶中的元素取出,从第一个桶开始,先放进去的先出来
        for m in range(len(counter)):
            while counter[m] != 0:
                arr[index] = bucket[m].pop(0)
                index += 1
                counter[m] -= 1
        # 这里一定要记得
        n *= 10
radix_sort(arr)
print(arr)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/304993.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32H5培训(二)性能提升与功耗优化

文章目录 1. 前言2. 性能提升3. 功耗优化参考&#xff1a; 1. 前言 本篇主要介绍STM32H5系列的性能提升和功耗优化方面的具体表现。H5系列相比于F4系列在性能和功能上有较大的升级&#xff0c;包括更强的内核、更高的主频、更快的flash访问速度、更丰富的通信接口和先进的安全…

【算法Hot100系列】有效的数独

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

在wsl中安装miniconda

下载安装包 打卡miniconda的官网https://docs.conda.io/projects/miniconda/en/latest/,下载下来安装包&#xff0c;或者直接在乌班图中运行命令wget https://repo.anaconda.com/miniconda/Miniconda3-py38_23.5.2-0-Linux-x86_64.sh,等待下载完毕 安装 到下载目录下执行命令…

Spring MVC入门案例!!!

1.先加入架包&#xff08;我这里使用了tomcat插件&#xff0c;你也可以直接按照原本的方式使用tomcat&#xff09; <packaging>war</packaging><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8&l…

R语言(12):绘图

12.1 创建图形 12.1.1 plot函数 plot(c(1,2,3),c(1,2,4)) plot(c(1,2,3),c(1,2,4),"b") plot(c(-3,3),c(-1,5),"n",xlab "x",ylab "y")12.1.2 添加线条&#xff1a;abline()函数 x <- c(1,2,3) y <- c(1,3,8) plot(x,y) lm…

飞塔FortiGate-1000C设备引进助力易天构建网络安全新防线

在当今数字化浪潮的推动下&#xff0c;企业对网络安全的需求日益迫切。为了应对不断升级的网络威胁&#xff0c;给客户提供最为优质的产品&#xff0c;易天引进了最新兼容性测试设备飞塔FortiGate-1000C&#xff0c;为光模块产品交付提供了更强劲的性能保障。 FortiGate-1000C是…

还不了解 Dockerfile 的同学不是好测试人

前言&#xff1a;近年来 Docker 非常火&#xff0c;想要玩好 Docker 的话 Dockerfile 是绕不开的&#xff0c;这就好比想要玩好 Linux 服务器绕不开 shell 道理是一样的。 今天我们就来聊一聊 Dockerfile 怎么写&#xff0c;那些指令到底是什么意思。 一、先来看一个简单的 D…

消息中间件

一、 消息中间件的介绍 消息中间件属于分布式系统中的子系统&#xff0c;关注数据的发送和接收&#xff0c;利用高效、可靠的异步消息传递机制&#xff0c;对分布式系统中的各个子系统进行集成。 1.1 为什么使用消息中间件 异步 解耦 缓冲能力 伸缩性 提高系统扩展性1.2 消息…

C++11新特性(也称c++2.0)

目录 1.输出C版本&#xff1a;cout << __cplusplus << endl; 2.Uniform Initialization(一致性初始化) 3.initializer_list&#xff08;形参&#xff09; 4.explicit 5.for循环的新用法 6.default和delete 7.Alias Template&#xff08;模板化名&#xff09…

Linux ssh 实现远程免密登录

一、背景 我搭建了一个 zookeeper 集群&#xff0c;写了一个 shell 脚本来控制集群的启动和关闭&#xff0c;但是我发现每次我执行 shell 脚本的时候&#xff0c;都需要我输入各个服务器的密码才可以运行&#xff0c;感觉很麻烦。shell 脚本里面连接其他服务器用的就是 ssh 的方…

HarmonOS 日期选择组件(DatePicker)

本文 我们一起来看基础组件中的 DatePicker 这就是 日程开发中的日期组件 他可以创建一个日期的范围 并创建一个日期的滑动选择器 这里 我们先写一个组件的骨架 Entry Component struct Index {build() {Row() {Column() {}.width(100%)}.height(100%)} }然后 我们先在Column组…

Redis:原理速成+项目实战——Redis实战5(互斥锁、逻辑过期解决缓存击穿问题)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;Redis&#xff1a;原理速成项目实战——Redis实战4&#xff08;解决Redis缓存穿透、雪崩、击穿&#xff09; &#x1f4da;订阅专…

想学习云计算么?教你如何免费白嫖微软和AWS的云资源一年

在这个数字化飞速发展的时代&#xff0c;云计算已成为IT行业的未来趋势。作为一名渴望进步的IT专业人员&#xff0c;掌握云计算不仅意味着技能的提升&#xff0c;更是升职加薪、拓宽职业道路的重要跳板。这里教你如何免费利用微软Azure和亚马逊AWS的云资源&#xff0c;为期一年…

oracle11范围表空间实例

1.表分区&#xff1a;范围分区&#xff0c;散列分区&#xff0c;列表分区&#xff0c;组合分区&#xff0c;inetrval分区 范围分区&#xff1a;商品零售表&#xff0c;按照销售日期所在的季度创建4个分区 --先建立表空间&#xff1a;临时表空间是不可以存放数据的&#xff0c;…

Python——数据类型转换

# 将数字类型转换成字符串 num_str str(111) print(type(num_str), num_str) \# 将浮点类型转换成字符串 float_str str(12.34) print(type(float_str), float_str) # 将字符串转变成数字 num int("234") print(type(num)) # 将字符串转变成浮点型 num2 float(&q…

Java学习笔记-day05-响应式编程初探-自定义实现Reactive Streams规范

最近在学响应式编程&#xff0c;这里先记录下&#xff0c;响应式编程的一些基础内容 1.名词解释 Reactive Streams、Reactor、WebFlux以及响应式编程之间存在密切的关系&#xff0c;它们共同构成了在Java生态系统中处理异步和响应式编程的一系列工具和框架。 Reactive Streams…

12.8-1.8

2023.12.8 redis容器 docker run -p 6379:6379 --name redis -v /mydata/redis/data:/data -v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redis.conf redis.conf不存在&#xff0c;需先在宿主机创建该目录下文件&#xff0c…

知识点整理[(GraphGeo)RELATED WORK]

2 RELATED WORK 2.1 IP Geolocation 问题一:IP定位预测方法之一:Data mining-based methods 回答: 依赖于在公开的资源中挖掘位置线索来对目标IP(target IP)进行地理定位。其中一些数据分析了来自与IP相关的数据库,如WHOIS数据库和DNS的数据。 (1)例如,Moore等…

Transformer架构的局限已凸显,被取代还有多久?

江山代有才人出&#xff0c;各领风骚数百年。这句话无论是放在古往今来的人类身上&#xff0c;还是放在当今人工智能领域的大模型之上&#xff0c;都是最贴切不过的。无论是一个时代的伟人&#xff0c;还是统治一个领域的技术&#xff0c;最终都会有新的挑战者将其替代。Transf…

2024-01-09 Android.mk 根据c文件名插入特定的宏定义,我这里用于定义log LOG_TAG 标签

一、在Android的构建系统中&#xff0c;使用Android.mk构建脚本可以根据特定需求来定义宏。如果你想根据C文件的名称来插入特定的宏定义&#xff0c;可以使用条件语句检查文件名&#xff0c;并相应地设置宏。 在Android的构建系统中&#xff0c;使用Android.mk构建脚本可以根据…