两个指针(位置)的妙用

C/C++中的指针变量可以相互赋值,使得它们指向同一块地址空间 两个指针变量可以相互赋值吗? int *p, *q; p=q; 这样写是什么意思?是p指向q吗? 答:1.两个指针变量之间可以相互赋值,p和q都是int类型的指针。 p=q表示将q所指向的int类型变量的地址赋给p 2.两个都是指针,所以是p的值等于q 如果p不是指针,那么p=q是p等于q指向的值 3.可以这样写,前提好像是q有确定的地址指向,然后用此语句赋值则表示,指针p和指针q指向相同的地址空... 阅读详情

使用两个指针可以轻松的解决许多算法问题,归纳出如下几种

1、  判断链表是否带环

带环链表的判断是链表中经常考察的内容。一个循环链表可以无休止地遍历下去。我们可以定义两个指针,一个快指针一个慢指针,如果在遍历到尾端前二者相遇,那么链表就是有环链表

  1. bool haveCycle(LinkList * Head)  
  2. {  
  3.     if (!Head)  
  4.     {  
  5.         return false;  
  6.     }  
  7.     LinkList * fast=Head;  
  8.     LinkList * slow=Head;  
  9.     while (!fast)  
  10.     {  
  11.         if (fast==slow) //如果两指针相遇,则返回真  
  12.         {  
  13.             return true;  
  14.         }  
  15.         fast=fast->next;  
  16.         if (!fast)  
  17.         {  
  18.             return false;  
  19.         }  
  20.         fast=fast->next;   //快指针走两步  
  21.         slow=slow->next;   //慢指针走一步  
  22.     }  
  23.     return false;  
  24. }  


 

2、  求链表中倒数第K个节点

如果用普通的思路得遍历两遍链表,第一遍先求出链表的总长度N,然后第二遍走到第N-k个节点,这个节点就是所求的节点。如果链表很长,那么遍历两次的话就很费时,我们用两个指针的方法遍历一次链表即可,先让一个指针走K步,然后两个指针再一起走,直到第一个指针遍历到链表末尾。

  1. LinkList * FindRevK(LinkList * Head,int k)  
  2. {  
  3.     if (!Head)  
  4.     {  
  5.         return NULL;  
  6.     }  
  7.     LinkList * first=Head;  
  8.     LinkList * second=Head;  
  9.     for (int i=0;i<k;i++)  //先让first走K步  
  10.     {  
  11.         if (!first)  
  12.         {  
  13.             return NULL; //链表长度小于K则返回NULL  
  14.         }  
  15.         first=first->next;  
  16.     }  
  17.     while (first)  
  18.     {  
  19.         first=first->next;  
  20.         second=second->next;  
  21.     }  
  22.     return second;  
  23. }  


 

3、  二分法查找某个数

用经典的二分法在一个有序数组中可以以log(n)的时间复杂度查找出给定的数。同样也是设定两个位置下表,low与high。由于该方法大家都熟悉不过了,只把代码贴上来就行了

  1. int search(int array[],int n,int value)  
  2. {  
  3.     if (!array||n<0)  
  4.     {  
  5.         return -1;  
  6.     }  
  7.     int low=0;  
  8.     int high=n-1;     
  9.     while (low<high)  
  10.     {  
  11.         int med=low+(high-low)/2; //这样可以防止low+high发生溢出  
  12.         if (array[med]<value)  
  13.         {  
  14.             low=med+1;  
  15.         }  
  16.         else if (array[med]>value)  
  17.         {  
  18.             high=med-1;  
  19.         }  
  20.         else  
  21.             return med;  
  22.     }  
  23.     return -1;  
  24. }  

 

4、  在一个有序数组中找出和为N的两个数

定义两个位置low和high,一个在开始处,一个在结尾处,如果二者之和大于N,high递减,如果二者之和小于N则low递增,直到和为N或者二者相遇为止

  1. void findNum(int * array,int arraysize,int N,int & low,int & high)  
  2. {  
  3.     low=0;  
  4.     high=arraysize-1;  
  5.     while (low<high)  
  6.     {  
  7.         if (low+high==N)  
  8.         {  
  9.             return;  //和为N,返回  
  10.         }  
  11.         else if (low+high<N)  
  12.         {  
  13.             low++;  
  14.         }  
  15.         else  
  16.         {  
  17.             high--;  
  18.         }  
  19.     }  
  20.     //没有两个数的和为N,则置下表为-1  
  21.     low=-1;  
  22.     high=-1;  
  23. }  

5、  输入一个正数n,输出所有和为n连续正数序列

输入 15
输出
15=1+2+3+4+5
15=4+5+6
15=7+8

我们可用两个数low和high分别表示序列的最小值和最大值。首先把low初始化为1,high初始化为2。如果从low到high的序列的和大于n的话,我们向右移动low,相当于从序列中去掉较小的数字。如果从low到high的序列的和小于n的话,我们向右移动high,相当于向序列中添加high的下一个数字。一直到low等于(1+n)/2,因为序列至少要有两个数字

  1. void printResult(int low,int high,int num)  //该函数实现将low到high之间的数输出到屏幕上  
  2. {  
  3.     cout<<num<<"=";  
  4.     for (int i=low;i<high;i++)  
  5.     {  
  6.         cout<<i<<"+";  
  7.     }  
  8.     cout<<high<<endl;  
  9. }  
  10. void consecutiveN(int num)  
  11. {  
  12.     int low=1,high=2;  
  13.     int sum=low+high;  
  14.     while (low<(num+1)/2)  
  15.     {  
  16.         if (sum==num)  
  17.         {  
  18.             printResult(low,high,num); //输出结果  
  19.             sum-=low;  
  20.             low++;  
  21.         }  
  22.         while(sum<num)  
  23.         {  
  24.             high++;  
  25.             sum+=high;  
  26.         }  
  27.         while(sum>num)  
  28.         {  
  29.             sum-=low;  
  30.             low++;  
  31.         }  
  32.     }  
  33. }  

6、 输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分

如果不考虑时间复杂度,最简单的思路应该是从头扫描这个数组,每碰到一个偶数时,拿出这个数字,并把位于这个数字后面的所有数字往前挪动一位。挪完之后在数组的末尾有一个空位,这时把该偶数放入这个空位。由于碰到一个偶数,需要移动O(n)个数字,因此总的时间复杂度是O(n2)。

要求的是把奇数放在数组的前半部分,偶数放在数组的后半部分,因此所有的奇数应该位于偶数的前面。也就是说我们在扫描这个数组的时候,如果发现有偶数出现在奇数的前面,我们可以交换他们的顺序,交换之后就符合要求了。因此我们可以维护两个指针,第一个指针初始化为数组的第一个数字,它只向后移动;第二个指针初始化为数组的最后一个数字,它只向前移动。在两个指针相遇之前,第一个指针总是位于第二个指针的前面。如果第一个指针指向的数字是偶数而第二个指针指向的数字是奇数,我们就交换这两个数字

  1. void Reorder(int *pData, unsigned int length, bool (*func)(int));  
  2. bool isEven(int n)  
  3. {  
  4.     return (n & 1) == 0; //判断一个数字是不是偶数并没有用%运算符而是用&。理由是通常情况下位运算符比%要快一些  
  5. }  
  6. void ReorderOddEven(int *pData, unsigned int length)  
  7. {  
  8.     if(pData == NULL || length == 0)  
  9.         return;   
  10.     Reorder(pData, length, isEven);  
  11. }  
  12. void Reorder(int *pData, unsigned int length, bool (*func)(int))  
  13. {  
  14.     if(pData == NULL || length == 0)  
  15.         return;   
  16.     int *pBegin = pData;  
  17.     int *pEnd = pData + length - 1;   
  18.     while(pBegin < pEnd)  
  19.     {  
  20.         if(!func(*pBegin)) //从前半部分找出第一个偶数  
  21.         {  
  22.             pBegin ++;  
  23.             continue;  
  24.         }  
  25.         if(func(*pEnd))  //从后半部分找出第一个奇数  
  26.         {  
  27.             pEnd --;  
  28.             continue;  
  29.         }  
  30.         //二者交换  
  31.         int temp = *pBegin;  
  32.         *pBegin = *pEnd;  
  33.         *pEnd = temp;  
  34.     }  
  35. }  

这道题有很多变种。这里要求是把奇数放在偶数的前面,如果把要求改成:把负数放在非负数的前面等,思路都是都一样的


提取仪表盘指针位置 img= imread('2.jpg');%读取图像 imagebeffor=rgb2gray(img);%转为灰度图像 figure; imshow(image); title('滤波后的图像');%显示图像 level=graythresh(image);%计算全局阈值 imageth=im2bw(image,level);%二值化 figure; imshow(imageth); ti... 阅读详情

相关推荐

DeepLearning tutorial(7)深度学习框架Keras的使用-进阶

上一篇文章总结了Keras的基本使用方法,相信用过的同学都会觉得不可思议,太简洁了。十多天前,我在github上发现这个框架的时候,关注Keras的人还比较少,这两天无论是github还是微薄,都看到越来越多的人关注和使用Keras。所以这篇文章就简单地再介绍一下Keras的使用,方便各位入门。主要包括以下三个内容: 训练CNN并保存训练好的模型。 将CNN用于特征提取,用提取出来的特征训练SVM。

wepon的专栏 2万+

指针间的互相赋值

本篇文章分为三个大的部分 大标题1提出权限“概念”,大标题2验证赋值规则 大标题3、4、5是我的个人理解。 大标题6是最直接的结论。 提醒 看懂这篇文章可能需要你知道并理解四种指针的定义,这是基础。当然如果真的不懂,可以直接去文尾记住结论。 四种指针详解戳这https://chouxianyu.github.io/2018/08/26/常量指针与指针常量/#more 指针修改指向内容的权...

weixin_30871293的博客 2439

IC618新手避坑指南:从零在Linux上配置Cadence Virtuoso环境(含cds.lib文件详解)

本文详细介绍了在Linux系统上配置Cadence Virtuoso IC618环境的完整指南,特别针对新手常见问题提供解决方案。重点解析了cds.lib文件的关键配置,包括库路径定义和工艺库管理,并分享了高效工作流设置和典型问题排查技巧,帮助工程师快速搭建稳定的EDA设计环境。

weixin_26805597的博客 557

C语言指针相互赋值

C语言指针相互赋值 首先要记住指针变量和其他普通变量一样,使用前不仅要定义,还要进行赋值。未经赋值的指针变量不能使用,否则将会造成系统混乱,甚至死机。指针变量的赋值只能赋予地址 例如: #include <cstdio> void swap(int *p1,int *p2){ int *temp; *temp=*p1;//此语句有问题,因指针变量temp定义后未具体指向,所以*temp无意义。 *p1=*p2; *p2=*temp; ​ } int main(){

羽的博客 1万+

Android 13/14/15 默认授权应用权限的实现方法

Android版本修改方式实现原理13/14修改Permission.java将所有权限标记为Normal权限15修改DeviceIdleController.java + DefaultPermissionGrantPolicy.java监听应用安装并主动授权。

m0_60898338的博客 2916

VC Spyglass CDC实战:如何快速定位和解决重汇聚问题(附详细调试步骤)

本文深入探讨了在SoC设计中利用VC Spyglass进行CDC验证时,如何高效定位和解决棘手的重汇聚问题。通过实战演练,详细解析了重汇聚的本质、VC Spyglass的检测逻辑,并提供了从报告筛选、GUI原理图分析到制定设计修复或约束豁免方案的全套调试步骤,帮助工程师快速攻克这一常见验证难题。

weixin_29219539的博客 755

共享内存不能使用指针《转载》

<br />好象是腾讯面试的第一个问题,当时就懵了,从来没有想过这个问题,然后也没有怎么考虑就说应该可以吧。回来一想便知道这是不可以的。A进程创建共享内存,如果共享的数据里面包含了指针那么指针指向的地址是A进程地址空间的某个逻辑地址,在B进程访问该地址肯定要出错的。下面的示例代码演示了这个错误。<br />      A进程执行下面的代码,它往共享内存里面放的是一个结构体,其中有一个指针指向一个常量字符串。该程序运行会输出共享内存映射到它地址空间的位置。 #include <stdlib.h><br />

qiuxiaolong007的专栏 3719

神州数码OSPF实战配置详解(手把手教学)

本文提供神州数码设备上OSPF基础配置的详细实战教程。通过搭建典型的两台三层交换机互联实验环境,手把手演示了VLAN创建、接口IP配置、OSPF进程启动、Router-ID设置及网络宣告等核心步骤,并分享了邻居状态验证、路由检查及常见排错方法,帮助网络工程师快速掌握神州数码OSPF的配置要点与操作技巧。

weixin_29210727的博客 81

【C语言】文件指针与文件位置指针,位置指针相关操作库函数

1 文件指针 文件指针是指向一个文件的指针,确切的将是指向用文件这个结构体所定义的对象的起始地址,文件指针的移动是指在文件之间来移动, 比如: FILE * fp; fp = fopen("/programe/test.txt","a+"); fp就表示文件指针。 问题:文件指针能不能在文件之间来回移动? 如果能的话,需要先释放文件指针吗? 如果不能的话,是为什么,是因为这个指

省 2万+

大疆无人机图像传输延时优化全解析:从Lightbridge到OcuSync的实战技巧

本文深入解析大疆无人机图像传输延时优化,对比Lightbridge与OcuSync两大核心通信协议的技术差异与实战表现。文章详细拆解了从传感器采集到屏幕显示的完整延时链条,并提供了从环境频段选择、硬件升级到软件设置的全方位优化技巧,帮助飞手与开发者显著降低图传延时,提升操控体验与作业效率。

weixin_29163857的博客 307

大厂校招:星宸科技嵌入式面试及参考答案(5万字长文)

当一个新的硬件设备被插入系统时,内核会发送一个设备事件通知 udev,udev 会根据设备的属性和规则,为该设备创建一个合适的设备文件。通过去除不必要的驱动程序、禁用不需要的功能、选择合适的内核配置选项、优化内核编译选项和定制内核模块等方法,可以减小内核的大小和复杂性,提高系统的性能和稳定性。上半部通常是在中断关闭的情况下执行的,以确保中断处理的原子性。处理碎片化内存是内存管理中的一个重要问题,可以采用内存压缩、内存池管理、伙伴系统、首次适应算法和最佳适应算法等方法来减少内存碎片的产生,提高内存的利用率。

大模型大数据攻城狮的专栏 2929

链表中“快慢指针”的妙用

本文介绍了链表操作中的几种常见问题及其解决方法。

qq_74204532的博客 991

【2026年华为暑期实习(AI)-6月3日-第一题- 选择题】(题目+思路+Java&C++&Python解析+在线测试)

本文摘要: 本文探讨了深度学习与计算机科学中的多个关键概念和技术,包括CUDA双缓冲技术、神经网络训练问题、优化算法、概率模型、Transformer架构特性、量化技术、损失函数选择等。通过20道选择题和多项选择题,涵盖了梯度消失/爆炸、神经元死亡、牛顿迭代法、朴素贝叶斯分类、Adam优化器、KV Cache压缩等核心知识点。特别关注了大模型训练中的计算效率、数值稳定性问题,以及实际应用场景如客服Agent的记忆机制优化。题目设计既考察基础理论(如概率分布、指数分布特性),又结合前沿技术(如MoE架构、注意

m0_73659489的博客 81

C语言中文件指针,文件位置指针,详细解析

文件指针未移动的原因,文件指针位置解析

qq_41672971的博客 7776

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

C语言指针在数组之中的妙用

数组指针其实就是行指针,本文着重讲解了一维和二维,如果实际代码中遇到了更多维数的指针也一样可以运用这种嵌套的思想来理解。编程最重要的就是理解其底部的思想。

小新Kelvin 1882

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

双指针算法的妙用:提高代码效率的秘密(3)

本篇文章到这也就全部结束了,希望各位好好理解我讲述的两道算法题,我会坚持每日两道算法题的更新,希望各位读者朋友在看完以后,如果我文章有一些错误的话,及时在评论区点出或者私信我,我定会及时修改,讲题的时光总是很短暂,那么各位大佬们,我们下一篇文章见啦~

effort123_的博客 1587

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

指针的妙用

指针或者叫做索引、下标,灵活使用可以完成比较巧妙地效果 快慢指针 快慢指针,表示两个指针,移动的速度不同,通常一般快指针速度是慢指针速度的两倍,通过两个指针相对位置的关系可以解决一些问题,例如:查找链表环起点问题 算法步骤: 快慢指针都从链表起点开始移动(两个指针速度插一倍),当两个指针再次相遇时停止本次移动 ListNode fast, slow; fast = slow = head; while(fast != null && fast.next != null) { fast

卢平光的博客 705

指针的进阶

一、字符指针 二、指针数组 三、数组指针 五、函数指针 六、函数指针数组 七、指向函数指针数组的指针 八、回调函数

qwertasx的博客 1856

链表的快慢指针的妙用

链表的快慢指针的使用 1. 环形链表 LeetCode题目 141. 环形链表 题目描述 给定一个链表,判断链表中是否有环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。 示例 1: 输入:head = [3,2,0,-4], pos = 1 输出:true 解释:链表中有一个环,其尾部连接到第二个节点。 示例 2: 输入:head = [1,2], pos = 0 输出:true 解释:链表中有一个环,其

liuhao192的博客 220

虚表指针、虚函数指针位置

一图以镇之 下面开始试验 class A{ public: virtual void a() {}; }; class B{ public: virtual int b(){return 3;} }; class C : public A,B{ public: virtual int c(){return 4;} }; 首先定义三个类,C继承A和B,那么根据经验,C中会有一个指向A和B的虚表指针,如此我们分别打印sizeof(...)可以得到8 8 16的结果 那...

Runner_of_nku的博客 3736

字符串二级指针,妙用

在C中,字符串处理还是比较复杂的,不能直接赋值,除非是字符指针才能直接赋值。字符串通常是字符数组表示,字符数组还得用strcpy()才能赋值。 所以,在处理字符串的时候,经常会遇到二级指针。下面来总结一下自己学到的东西: 1. 字符数组和字符指针 把字符数组赋值给一个字符指针,直接赋值就可以,不需要在字符数组前加取地址符&。 2. 给字符数组赋值 不能直接用赋值符号’=‘,而是用...

IPGsoz的博客 1841

两个指针相减

如果两个指针指向同一个数组,它们就可以相减,其结果为两个指针之间的元素数目。      假设我住在广场路124号,Mag住在广场路142号,每家之间的地址间距是2(在我这一侧用连续的偶数作为街道地址),那麽Mag家就在我家往前(142-124)/2家,也就是说可以得到我们两家之间相隔8家。      也就是说可以利用两个指向同一数组的指针相减得到两个指针之间元素的个数。      如果两个指针不是指向同一个数组,它们相减就没有意义了。      C本身无法防止非法的指针减法运算,它无法为你提出任何警

gdmmhym的专栏 3万+
上一篇: 将m个相同的球全部放到n个相同的盒子里面有几种放法,盒子不能为空
下一篇: 面试腾讯实习
AstrayLinux
博客等级 码龄15年 55粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值