【初阶数据结构与算法】沉浸式刷题之顺序表练习(顺序表以及双指针两种方法)

在这里插入图片描述

文章目录

  • 顺序表练习
    • 1.移除数组中指定的元素
      • 方法1(顺序表)
      • 方法2(双指针)
    • 2.删除有序数组中的重复项
      • 方法1(顺序表)
      • 方法2(双指针)
    • 3.双指针练习之合并两个有序数组
      • 方法1(直接排序)
      • 方法2(双指针)

顺序表练习

   在顺序表练习中我们会首先使用我们学过的顺序表来解决,然后再同时介绍一下其它方法,在练习开始之前我们要说明一个东西,就是我们之前不是写好了一个顺序表吗?我们等一下就直接全部复制过来用
   那么是不是就说明我们以后要用数据结构做题就必须把它手写一遍吗?这是不需要的,后面我们会介绍C++,在C++中的STL中有现成的可以用,现在我们还没有介绍到,就复制我们写过的数据结构来做题
   在做题过程中,我们也会计算这些方法的时间复杂度和空间复杂度,也是对之前内容的一个复习

1.移除数组中指定的元素

题目链接:https://leetcode.cn/problems/remove-element/description/

方法1(顺序表)

   我们先来看看题目描述:
在这里插入图片描述
   题目中的第一个用例:
在这里插入图片描述
   题目给出的函数模型:
在这里插入图片描述
   根据上面的图片描述,我们基本明确了题意,就是给我们一个数组和一个值,然后把数组中和这个值相等的元素移除掉,最后返回处理后的数组中的有效元素个数
   方法1的思路就是直接使用我们的顺序表,在顺序表中我们提供了查找方法,并且提供了删除指定位置元素的方法,我们就可以在顺序表中查找要删除的元素,然后把返回来的下标作为参数传给删除函数
   首先我们把写过的顺序表拷贝到题目中,在使用顺序表之前,我们要创建一个顺序表,并且使用初始化方法对它初始化,为了防止忘记销毁顺序表,我们可以先把顺序表的销毁也一起配套写上
   随后把数组中的内容尾插到我们的顺序表,我们才能使用顺序表对数据进行操作,如下:

int removeElement(int* nums, int numsSize, int val) 
{int i = 0;SL sl;SLInit(&sl);for(i = 0; i<numsSize; i++){SLPushBack(&sl,nums[i]);}SLDestroy(&sl);
}

   随后我们就设计一个循环,让它能够一直找题目给出的元素,然后每找到一个就调用删除方法把它删除,那么循环的结束条件是什么呢?我们可以根据查找方法的返回值来设计,如果没有在顺序表中找到对应的元素会返回-1
   那么我们就判断它的返回值是否是-1,如果不是就进入循环将对应的元素删除,是的话就结束循环,如下:

while(SLFind(&sl,val) != -1)
{int ret = SLFind(&sl,val)SLErase(&sl,ret);
}

   处理完毕之后我们就把顺序表中的内容重新放入原数组,并且将数组有效元素个数记录下来,完整代码如下:

int removeElement(int* nums, int numsSize, int val) 
{int i = 0;SL sl;SLInit(&sl);for(i = 0; i<numsSize; i++){SLPushBack(&sl,nums[i]);}while(SLFind(&sl,val) != -1){int ret = SLFind(&sl,val);SLErase(&sl,ret);}for(i = 0; i<sl.size; i++){nums[i] = sl.arr[i];}int k = sl.size;SLDestroy(&sl);return k;
}

   我们看看提交的结果:
在这里插入图片描述
   可以看到最后通过了,我们来分析一下代码的时间复杂度和空间复杂度,第一个和第二个for循环都是O(N),关键在于第二个while循环的时间复杂度
   由于我们的查找方法和删除方法时间复杂度都是O(N),外层有一个while循环,所以时间复杂度就是O(N^2),不是很好的一个时间
   接着来看空间复杂度,我们为了在顺序表中操作数组的数据,所以把数组中的数组全部放入了顺序表,所以顺序表会额外开辟数组元素大小的空间,空间复杂度为O(N)
   我们知道这个时间复杂度和空间复杂度都不是很好,所以我们要接着介绍另一个方法

方法2(双指针)

   这里的双指针不是创建两个指针变量,而是指数组中的下标,因为在数组中我们能够通过下标找到对应的元素,与指针很像,所以叫双指针
   具体方法就是创建两个整型变量src和dest,这两个名字在我们指针章节出现得不少,src代表源,dest代表目的地
   在双指针算法中,我们的思路很简单,就是首先让src和dest都指向数组的第一个元素,随后我们就看src位置上的值是否是题目给出的val,如果是我们就直接让src往后走一步
   如果不是,我们就把src位置上的值赋给dest,随后让dest和src都往后走一步,接下来我们就演示一下第一个示例的推演,如图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
   有了上图的分析,我们就可以来实现一下代码了,首先创建两个整型变量src和dest作为我们的双指针,初始情况下让它们都为0
   随后创建一个循环,循环条件就是src<numsSize,因为src是数组中的下标,要保证它不能越界,接着我们就进行判断,如果src位置的值等于dest位置的值,那么直接让src++
   否则的话就是不等于,那么把src位置的值赋值到dest位置,随后让它们都++,如下:

while (src < numsSize)
{if (nums[src] == val){src++;}else{nums[dest++] = nums[src++];}
}

   最后我们直接返回dest即可,完整代码如下:

int removeElement(int* nums, int numsSize, int val) 
{int src = 0;int dest = 0;while(src < numsSize){if(nums[src] == val){src++;}else{nums[dest++] = nums[src++];}}return dest;
}

   最后我们提交一下就通过了,在双指针方法中,我们只有一个循环,时间复杂度为O(N),申请的空间也是常数个,所以时间复杂度为O(1),可以看到比使用顺序表的方法简便多了,时间复杂度和空间复杂度都降低了一个档次
   这道题的双指针法的本质就是,碰到了指定的元素就不管,直接跳过,然后把不是指定的元素放在前面,简单地说就是一个在前面探路,一个在后面接收

2.删除有序数组中的重复项

题目链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-array/description/

方法1(顺序表)

   在这个题目中,方法1我们还是使用顺序表来做,我们首先来看看题目描述:
在这里插入图片描述
题目的第一个示例:
在这里插入图片描述
题目给出的函数原型:
在这里插入图片描述
   根据上面图片的解释,我们大致明白了题目的要求,就是数组是相对有序的,然后我们要删除那些重复项,让数组里面的元素变得唯一,最后返回唯一的元素个数,至于其它位置的元素就不管了
   首先我们还是拷贝顺序表代码,以及创建、销毁顺序表,把数组中的数据尾插到顺序表中,上面讲过了,接着我们就来讲这道题不同的地方
   由于数组是相对有序的,所以相同的元素肯定是放在一起的,所以我们就可以写一个循环来判断前后两个元素是否相等,如果相等我们就删除当前的元素,每删除一个元素numsSize就减1,要特别注意的一个点是要保证下标的有效性,如下:

for (i = 0; i < numsSize; i++)
{if (i + 1 < numsSize && sl.arr[i] == sl.arr[i + 1]){SLErase(&sl, i);numsSize--;}
}

   但是如果我们去运行这段代码就会发现第二个示例会出错,如下:

[0,0,1,1,1,2,2,3,3,4]

   我们把这个示例放到VS中调试一下,如图:
在这里插入图片描述
   这个时候我们发现了问题,当i = 1时,将下标为1的元素删除了,所有后面的其它元素都往前挪动了一步,导致现在下标为1和2的元素又相等了
   但是本次循环结束了,下一次在循环中i要++变成了2,i+1变成了3,比较不了下标为1和2的元素了,也就导致了下标为1和2的元素相等没有处理,如果看不懂这里的分析也没有关系,自行调试一下就明白了
   那么怎么解决呢?其实也很简单,问题就出在删除一个相同元素后,其余元素都往前挪动了,但是循环结束了,i要++,就不会再比较移动后的i下标位置的元素和i+1下标的元素了
   所以我们为了能够让它删除元素后,多比较一次原本移动后的i下标位置的元素和i+1下标的元素,我们可以在删除一个元素后让i- -,这样处理后下次进入循环i的值就不会变化,代码如下:

for (i = 0; i < numsSize; i++)
{if (i + 1 < numsSize && sl.arr[i] == sl.arr[i + 1]){SLErase(&sl, i);numsSize--;i--;}
}

   当完成上面的步骤之后我们再把顺序表中的数据拷贝回原数组中,此时的numsSize就是有效的元素个数,完整代码如下:

int removeDuplicates(int* nums, int numsSize)
{SL sl;int i = 0;SLInit(&sl);for (i = 0; i < numsSize; i++){SLPushBack(&sl, nums[i]);}for (i = 0; i < numsSize; i++){if (i + 1 < numsSize && sl.arr[i] == sl.arr[i + 1]){SLErase(&sl, i);numsSize--;i--;}}for (i = 0; i < numsSize; i++){nums[i] = sl.arr[i];}SLDestroy(&sl);return numsSize;
}

   最后我们提交一下就可以通过了,在这个方法中,我们的时间复杂度也是很高的,达到了O(N^2),并且由于使用顺序表拷贝了原数组中的内容,空间复杂度也不低,达到了O(N),所以我们接下来介绍一个更好的方法

方法2(双指针)

   这道题还是可以使用我们的双指针法来做,上一题的双指针法的本质就是,碰到了指定的元素就不管,直接跳过,然后把不是指定的元素放在前面,本质就是一个在前面探路,一个在后面接收
   这道题也可以借鉴这样的思想,我们题目要求去掉相对有序的数组中的元素,说明相等的元素都是挨在一起的,我们还是可以定义两个变量src和dest,src在前面探路,dest在后面接收
   具体思路就是:初始情况下让dest指向第一个元素,而src指向第二个元素,因为如果它们都指向第一个元素,那么它们肯定就相等了,没有比较的必要,所以让src走到第二个元素的位置上
   然后我们就比较src和dest位置上的元素是否相等,如果相等我们就让让src++,其它什么都不做,如果不相等就让dest++,然后把src位置的值赋值到dest位置上,然后再让src++,听着可能有点懵,我们来画个图理解一下,就知道这个思路了
   具体的例子我们就参考题目给出的第一个示例,如下:
在这里插入图片描述
在这里插入图片描述
   有了上图的解析,我们现在就可以直接来写代码了,首先创建一个while循环,条件就是src<numsSize,因为src是数组的下标,不能越界
   然后如果src指向的元素等于dest指向的元素,就让src++,其它什么都不做,如果不相等,就让dest先++,再把src位置的元素赋值给dest位置的元素,最后让src++,如下:

while (src < numsSize)
{if (nums[src] == nums[dest]){src++;}else{dest++;nums[dest] = nums[src];src++;}
}

   写出来之后我们可以对它进行一下优化,让代码不那么臃肿,如下:

while (src < numsSize)
{if (nums[src] == nums[dest])src++;elsenums[++dest] = nums[src++];
}

   最后循环结束后我们再返回dest+1即可,完整代码如下:

int removeDuplicates(int* nums, int numsSize) 
{int src = 0, dest = 0;while(src < numsSize){if(nums[src] == nums[dest])src++;elsenums[++dest] = nums[src++];}return dest+1;    
}

   最后就可以成功提交代码了,我们再来分析一下双指针法的时间复杂度和空间复杂度,我们只使用了一个循环,时间复杂度为O(N),只申请了有限个大小的空间,所以空间复杂度为O(1),相较于上一个方法优化了许多

3.双指针练习之合并两个有序数组

题目链接:https://leetcode.cn/problems/merge-sorted-array/description/

方法1(直接排序)

   虽然这道题我们是用来练习双指针的,但是我们还是有必要知道一下这道题的其它解决办法,并且这个解决方法还不难,所以放在这里简单说一下
   我们先来看看题目描述:
在这里插入图片描述
   题目第一个示例:
在这里插入图片描述
   题目给出的函数原型:
在这里插入图片描述
   题目的大致含义就是,给了我们两个数组,其中第一个数组nums1的大小是两个数组有效元素个数的和,因为我们后面要把nums2数组中的元素放到nums1中去,所以要保证nums1数组的大小足够
   首先题目还是告诉我们这两个数组是非递减的数组,也就是递增的数组,只是有可能有重复的数据,现在就要求我们将这两个有序的数组合并,并且保持合并后还是有序的
   第一个方法很简单,不是保持合并后还是有序吗,直接把nums2数组的数据先插入num1数组,然后对整个nums1数组进行排序,排序我们可以选择qsort函数,没有学过qsort函数的友友可以参考文章:【C语言】手把手带你拿捏指针(4)(含qsort函数详解)
   也可以选择我们之前学过的冒泡排序,但是其实冒泡排序的效率是比较低的,后面我们会把所有常见的排序算法都讲一下,比如快排,堆排等等,qsort函数的底层就是使用的快排实现
   代码的实现过程就不再多讲了,思路很简单,这里我们直接给出完整代码:

#include <stdlib.h>int int_cmp(const void* e1, const void* e2)
{return *(int*)e1 - *(int*)e2;
}void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) 
{ for(int i = 0; i<n; i++){ nums1[i+m] = nums2[i]; }  qsort(nums1, m+n, sizeof(int), int_cmp);
}

   可以看到代码的逻辑是很简单的,并且效率是很快的,因为qsort底层使用的是快排,时间复杂度仅仅为O(N * logN),空间复杂度也是O(1),那么还有没有更快的方法呢?当然有,就是我们马上介绍的双指针法

方法2(双指针)

   其实我们今天练习的三道题其实都很类似,所以都可以使用双指针来做,只是在这道题中我们有两个数组需要合并,我们还是可以试着用之前的思路来思考一下这道题,只是之前是一个数组,只需要一个src,这道题我们可以定义两个指针src1和src2
   之前的两个题思路就是,如果碰到相等的元素或者题目给出的元素,就把它跳过,使用后面的元素将它覆盖,而这道题我们该怎样做呢?
   首先就是第一个思路,我们定义src1指向nums1数组的第一个元素,src2指向nums2数组的第二个元素,然后由于要把最后的结果保存到nums1中,所以dest就指向nums1中的第一个元素
   随后我们比较src1指向的元素和src2指向的元素哪个小,哪个小就把它放到dest的位置上,然后让dest++,然后src1++或者src2++,最后循环这个步骤
   但是我们最后发现这个思路有点问题,问题出在nums1数组中,因为如果我们直接把数据放在dest,也就是从nums1数组的开头开始存放数据,会导致原本的nums1数组的数据被覆盖,我们举个例子,如图:
在这里插入图片描述
   此时我们就发现问题了,nums1中的数据会被覆盖,所以第一种思路并不可行,那么怎么避免数据被覆盖呢?这个时候我们就可以从nums1数组的最后面开始操作数据,也就是让我们的dest默认指向nums1数组的最后一个位置
   因为我们要保证nums1最后排序成相对递增,最后一个位置就要放最大的值,怎么办呢?我们可以让src1和src2分别指向nums1和nums2数组中有效元素的最后一个元素,然后它们两个指向的元素谁大就让它放入dest的位置
   然后让dest- -,以及src1- -或者src2- -,就这样一直从后往前找大放入dest位置,循环条件就是要让src1和src2都要大于等于0,因为它们是数组的下标,不能越界,最后就可以使得数组是相对递增的,这就是我们的第二个思路,接下来我们就用第一个示例来画个图理解一下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
   可以看到我们这里将两个数组合并到了nums1中,让数组nums1有序了,但是其实有一个问题,如果我们最后时src2先越界,那么说明nums2数组中的数据已经全部放入nums1了,循环结束了,剩下的nums1的数据也已经保持了有序,所以src2首先越界代码没有问题
   但是有可能下一次src1首先越界,说明nums1中原本的有效的元素已经放在nums1数组后面了,循环结束了,但是nums2数组还没有放完呀,这个时候就会出错,所以我们还需要在这个循环结束后用一个新的循环判断一下
   如果src2还大于等于0,说明nums2数组中的内容还没有全部移动到nums1中,此时我们只需要循环地让数组nums2中的元素移动到nums1的dest位置,接下来我们的代码才能完全没问题,如下:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) 
{int src1 = m-1;int src2 = n-1;int dest = m+n-1;while(src1>=0 && src2>=0){if(nums1[src1] > nums2[src2]){nums1[dest--] = nums1[src1--];}else{nums1[dest--] = nums2[src2--];}}while(src2 >=0){nums1[dest--] = nums2[src2--];}
}

   接着我们提交一下:
在这里插入图片描述
   可以看到代码成功通过了,我们再来分析一下这个代码的时间复杂度和空间复杂度,可以发现我们虽然有两个循环,但是实际上深入计算会发现两个循环的次数加起来为O(N),所以时间复杂度是标准的O(N)
   并且由于申请的是有限个空间,所以空间复杂度是O(1),我们就可以看出来了,虽然我们的快排很快,时间复杂度仅为O(N * logN),但是我们的双指针更快,只有O(N)

   那么今天的分享就到这里结束啦,我们今天使用了顺序表来做了两道题,用一个题来专门学习双指针算法,但是这三道题都使用了我们的双指针算法来解决,以后类似的题就可以使用双指针,效率是很高的
   不知道友友们有没有收获什么新知识呢,欢迎在评论区留言,有问题欢迎直接私信我
   那么今天就撤啦,bye~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【flask开启进程,前端内容图片化并转pdf-会议签到补充】

flask开启进程,前端内容图片化并转pdf-会议签到补充 flask及flask-socketio开启threading页面内容转图片转pdf流程前端主js代码内容转图片-browser端browser端的同步编程flask的主要功能route,def 总结 用到了pdf,来回数据转发和合成,担心flask卡顿,响应差,于是刚好看到threadi…

PADS的GND难解之谜——GND铺不上捅?GND焊盘上全是绿色叉号?

PADS难解之谜——GND覆不上铜&#xff1f;焊盘上全是叉号&#xff1f; 文章目录 PADS难解之谜——GND覆不上铜&#xff1f;焊盘上全是叉号&#xff1f;1、GND灌铜灌不上&#xff1f;2、GND焊盘上全是绿色叉号&#xff1f; 如果对你有帮助&#xff0c;就点赞收藏把&#xff01;(…

02- 模块化编程-007 Ltc1684( ADC16-Bit)采样显示

1、Ltc1684芯片介绍 该芯片是一款高精度的16位模数转换器(ADC)&#xff0c;适合于高精度仪器的开发&#xff0c;它能提供精准的模拟信号到数字信号的转换。 特性 采用 MSOP 封装的 16 位、250ksps ADC 单 5V 电源 低电源电流&#xff1a;850μA (典型值) 自动停机功能可把电源…

信息安全工程师(80)网络安全测评技术与工具

前言 网络安全测评是评估信息系统、网络和应用程序的安全性&#xff0c;以发现潜在的漏洞和威胁&#xff0c;并确保系统符合安全标准和政策的过程。 一、网络安全测评技术 渗透测试&#xff08;Penetration Testing&#xff09; 描述&#xff1a;通过模拟真实的攻击&#xff0c…

基于STM32的太阳跟踪系统设计

引言 本项目基于STM32微控制器设计了一个智能太阳跟踪系统&#xff0c;通过集成光敏传感器模块和电机控制系统&#xff0c;实现太阳能电池板的自动调节&#xff0c;以保持太阳能电池板始终垂直对准太阳&#xff0c;从而最大化光能的吸收效率。该系统通过实时监测太阳光的方向&…

新能源汽车与公共充电桩布局

近年来,全球范围内对新能源汽车产业的推动力度不断增强,中国新能源汽车市场也呈现蓬勃发展的势头,在政策与市场的共同推动下,新能源汽车销量持续增长。然而,据中国充电联盟数据显示,充电基础设施建设滞后于新能源汽车数量增长的现状导致充电桩供需不平衡,公共充电桩服务空白区域…

Qt中的Model与View 4:QStandardItemModel与QTableView

目录 QStandardItemModel API QTableView 导航 视觉外观 坐标系统 API 样例&#xff1a;解析一个表格txt文件 QStandardItemModel QStandardItemModel 可用作标准 Qt 数据类型的存储库。它是模型/视图类之一&#xff0c;是 Qt 模型/视图框架的一部分。它提供了一种基于…

【STM32】项目实战——OV7725/OV2604摄像头颜色识别检测(开源)

本篇文章分享关于如何使用STM32单片机对彩色摄像头&#xff08;OV7725/OV2604&#xff09;采集的图像数据进行分析处理&#xff0c;最后实现颜色的识别和检测。 目录 一、什么是颜色识别 1、图像采集识别的一些基本概念 1. 像素&#xff08;Pixel&#xff09; 2. 分辨率&am…

Request 和 Response 万字详解

文章目录 1.Request和Response的概述2.Request对象2.1 Request 继承体系2.2 Request获取请求数据2.2.1 获取请求行数据2.2.2 获取请求头数据2.2.3 获取请求体数据2.2.4 获取请求参数的通用方式 2.3 解决post请求乱码问题 掌握内容讲解内容小结 2.4 Request请求转发 3.HTTP响应详…

经典网络模型

文章目录 网络演变过程1、阻塞IO&#xff08;BIO&#xff09;实现缺点 2、非阻塞IO&#xff08;NIO&#xff09;实现改进后设置非阻塞IO缺点 3、IO多路复用第一版&#xff08;select/poll&#xff09;问题点改进缺点 4、IO多路复用第二版&#xff08;epoll&#xff09;5、信号驱…

从神经元到神经网络:深度学习的进化之旅

神经元、神经网络 神经元 Neuron )&#xff0c;又名感知机( Perceptron )&#xff0c;在模型结构上与 逻辑回归 一致&#xff0c;这里以一个二维输入量的例子对其进行进一步 的解释&#xff1a; 假设模型的输 入向 量是一 维特征向 (x1,x2). 则单神 经元的模型结构 如下…

面试题:Spring(一)

1. Spring框架中bean是单例么&#xff1f; Service Scope("singleton") public class UserServiceImpl implements UserService { }singleton : bean在每个Spring IOC容器中只有一个实例。prototype&#xff1a;一个bean的定义可以有多个实例。 2. Spring框架中的…

qt QFileSystemModel详解

1、概述 QFileSystemModel是Qt框架中的一个关键类&#xff0c;它继承自QAbstractItemModel&#xff0c;专门用于在Qt应用程序中展示文件系统的数据。这个模型提供了一个方便的接口&#xff0c;使得开发者可以轻松地在应用程序中集成文件和目录的树形结构&#xff0c;并通过视图…

从0开始深度学习(26)——汇聚层/池化层

池化层通过减少特征图的尺寸来降低计算量和参数数量&#xff0c;同时增加模型的平移不变性和鲁棒性。汇聚层的主要优点之一是减轻卷积层对位置的过度敏感。 1 最大汇聚层、平均汇聚层 汇聚层和卷积核一样&#xff0c;是在输入图片上进行滑动计算&#xff0c;但是不同于卷积层的…

右旋圆极化散射后的stocks矢量 与T3矩阵的关系

T3矩阵如下 斯托克斯与T3的关系如下。 斯托克斯与T3均没有平均处理&#xff0c;即斯托克斯是完全极化波的&#xff08;一种琼斯矢量得到&#xff09;&#xff0c;T3是由一个散射矩阵得到&#xff0c;只有一个特征值。

【Unity】Unity拖拽在Android设备有延迟和卡顿问题的解决

一、介绍 在制作Block类游戏时&#xff0c;其核心的逻辑就是拖拽方块放入到地图中&#xff0c;这里最先想到的就是Unity的拖拽接口IDragHandler,然后通过 IPointerDownHandler, IPointerUpHandler 这两个接口判断按下和松手&#xff0c;具体的实现逻辑就是下面 public void On…

解线性方程组(二)

实验类型&#xff1a;●验证性实验 ○综合性实验 ○设计性实验 实验目的&#xff1a;进一步熟练掌握用Jacobi迭代法和Gauss-Seidel法解线性方程组的算法&#xff0c;提高编程能力和解算线性方程组问题的实践技能。 实验内容&#xff1a; 1)取初值性x(0)(0,0,0,0)T, 精度要求ε…

易语言模拟真人动态生成鼠标滑动路径

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

Charles抓包_Android

1.下载地址 2.破解方法 3.安卓调试办法 查看官方文档&#xff0c;Android N之后抓包要声明App可用User目录下的CA证书 3.1.在Proxy下进行以下设置&#xff08;路径Proxy->Proxy Settings&#xff09; 3.1.1.不抓包Windows&#xff0c;即不勾选此项&#xff0c;免得打输出不…

进程崩溃难以定位,日志分析五步搞定|OceanBase故障排查实践

作者&#xff1a;胡呈清&#xff0c;爱可生 DBA 团队成员&#xff0c;擅长故障分析、性能优化。 背景 Server 进程崩溃的常见原因包括程序bug、文件损坏、磁盘坏块以及内存坏块&#xff0c;这类故障通常较难分析和定位。 在OceanBase 集群部署时&#xff0c;系统会自动配置co…