`
wangxiaohigh
  • 浏览: 1423115 次
文章分类
社区版块
存档分类
最新评论

怎样不用中间变量temp 实现两个数交换

 
阅读更多
<wbr><p><span style="font-size:18px"><strong>第一类方法也是常用的方法,通过多次的数值计算来完成交换,到现在知道的有下面三种:</strong></span></p> <p><span style="font-size:18px"><strong>(1)加减法。</strong></span></p> <p><span style="font-size:18px"><strong>a = a + b;</strong></span></p> <p><span style="font-size:18px"><strong>b = a - b;</strong></span></p> <p><span style="font-size:18px"><strong>a = a - b;</strong></span></p> <p><span style="font-size:18px"><strong>该方法可以交换整型和浮点型数值的变量,但在处理浮点型的时候有可能出现精度的损失,例如对数据:</strong></span></p> <p><span style="font-size:18px"><strong>a = 3.123456</strong></span></p> <p><span style="font-size:18px"><strong>b = 1234567.000000</strong></span></p> <p><span style="font-size:18px"><strong>交换后各变量值变为:</strong></span></p> <p><span style="font-size:18px"><strong>a = 1234567.000000</strong></span></p> <p><span style="font-size:18px"><strong>b = 3.125000</strong></span></p> <p><span style="font-size:18px"><strong>很明显,原来a的值在交换给b的过程中发生了精度损失。</strong></span></p> <p><span style="font-size:18px"><strong>(2)乘除法。</strong></span></p> <p><span style="font-size:18px"><strong>a = a * b;</strong></span></p> <p><span style="font-size:18px"><strong>b = a / b;</strong></span></p> <p><span style="font-size:18px"><strong>a = a / b;</strong></span></p> <p><span style="font-size:18px"><strong>乘除法更像是加减法向乘除运算的映射,它与加减法类似:可以处理整型和浮点型变量,但在处理浮点型变量时也存在精度损失问题。而且乘除法比加减法要多一条约束:b必不为0。</strong></span></p> <p><span style="font-size:18px"><strong>可能经验上的某种直觉告诉我们:加减法和乘除法可能会溢出,而且乘除的溢出会特别严重。其实不然,采用这两种方法都不会溢出。以加减法为例,第一步的加运算可能会造成溢出,但它所造成的溢出会在后边的减运算中被溢出回来。</strong></span></p> <p><span style="font-size:18px"><strong>(3)异或法。</strong></span></p> <p><span style="font-size:18px"><strong>a ^= b;//a=a^b</strong></span></p> <p><span style="font-size:18px"><strong>b ^= a;//b=b^(a^b)=b^a^b=b^b^a=0^a=a</strong></span></p> <p><span style="font-size:18px"><strong>a ^= b;//a=(a^b)^a=a^b^a=a^a^b=0^b=b</strong></span></p> <p><span style="font-size:18px"><strong>异或法可以完成对整型变量的交换,对于浮点型变量它无法完成交换。</strong></span></p> <p><span style="font-size:18px"><strong>第二类方法更像是玩了一个文字游戏,此种方法采用了在代码中嵌入汇编代码的方法避免了临时变量的引入,但究其本质还是会使用额外的存储空间。此种方法可以有很多种,下边列出几种:</strong></span></p> <p><span style="font-size:18px"><strong></strong></span></p> <p><span style="font-size:18px"><strong>(1)使用xchg指令,这也是比较直观、容易想到的方法,因为xchg指令的功能就是交换源操作数和目的操作数的值,这里要使用额外寄存器来暂存变量。内嵌汇编代码如下:</strong></span></p> <p><span style="font-size:18px"><strong>_asm</strong></span></p> <p><span style="font-size:18px"><strong>{</strong></span></p> <p><span style="font-size:18px"><strong>mov eax,a</strong></span></p> <p><span style="font-size:18px"><strong>xchg b,eax</strong></span></p> <p><span style="font-size:18px"><strong>mov a,eax</strong></span></p> <p><span style="font-size:18px"><strong>}</strong></span></p> <p><span style="font-size:18px"><strong>(2)使用额外的栈。这里使用反向的出栈顺序来完成交换。内嵌代码有如下两种形式:</strong></span></p> <p><span style="font-size:18px"><strong>_asm</strong></span></p> <p><span style="font-size:18px"><strong>{</strong></span></p> <p><span style="font-size:18px"><strong>push a</strong></span></p> <p><span style="font-size:18px"><strong>push b</strong></span></p> <p><span style="font-size:18px"><strong>pop a</strong></span></p> <p><span style="font-size:18px"><strong>pop b</strong></span></p> <p><span style="font-size:18px"><strong>}</strong></span></p> <p><span style="font-size:18px"><strong>另一种形式:</strong></span></p> <p><span style="font-size:18px"><strong>_asm push a</strong></span></p> <p><span style="font-size:18px"><strong>a = b;</strong></span></p> <p><span style="font-size:18px"><strong>_asm pop a</strong></span></p> <p><span style="font-size:18px"><strong>(3)使用mov指令。这种方法使用额外寄存器来暂存一个变量的值。</strong></span></p> <p><span style="font-size:18px"><strong>_asm mov eax,a</strong></span></p> <p><span style="font-size:18px"><strong>a = b;</strong></span></p> <p><span style="font-size:18px"><strong>_asm mov b,eax</strong></span></p> <p><span style="font-size:18px"><strong>其实第二类方法并不合格,它虽然没有显式的使用临时变量,但还是会用到额外的存贮空间。不过也不能说没有必要掌握,从实用的角度看还是很“有用”的。不是有公司出过这样的面试题吗?“不使用加减法和异或法完成不使用中间变量交换两个数值型变量的值”。此时或许只好使用这种方法了。</strong></span></p> <wbr><br></wbr></wbr>
分享到:
评论

相关推荐

    JS实现不用中间变量temp 实现两个变量值得交换方法

    主要介绍了在JS中 实现不用中间变量temp 实现两个变量值得交换 ,需要的朋友可以参考下

    两个数据的交换

    对于两个数据交换,我们最常用的算法是: { temp = A; A = B; B = temp; } 这种算法采用一个临时变量temp,做中间媒介;有时候你是否想过一个问题不要临时变量能实现这个交换吗?

    C#基础入门之算法:交换

    两个变量的交换也需要一只“空杯子”,就是中间变量: string a="振刚";//第一个变量 string b="文峰";//第二个变量 string temp;//中间变量 //第一步:将变量a赋值给中间变量 temp=a;//如同牛奶倒入空杯 //第二步...

    Python中的四种交换数值的方法解析

    通过新添加中间变量temp的方式,这个方法是最简单的,每个语言都适用。 方法二 Python独有的方法,一行代码就能搞定,直接将两个变量放到元组。 方法三 这个方法采用加减法来交换。不考虑效率,能达到交换的效果就行 ...

    数据结构与算法.xmind

    递归拆分出两个有序的数组,从mid的位置开始拆分,递归出口:只有一个值的时候就不用拆分了 合并两个有序的数据 分别往两个数组填充已有序的数据 比较两个数组的值谁小,谁小就放到我们的...

    11.第十一章 指针.txt

    与指针相关的两个运算符: (1)&:取地址运算符 一般形式: &变量名 表示取一个内存变量的地址。 (2)*:指针运算符(或称“间接访问”运算符) 一般形式: *指针变量名 通过指针变间接访问指针变量所...

    Java位运算的应用

    (9)不用temp交换两个整数 void swap(int x , int y) { x ^= y; y ^= x; x ^= y; } (10)计算绝对值 int abs( int x ) { int y ; y = x &gt;&gt; 31 ; return (x^y)-y ; //or: (x+y)^y } (11)取模运算转化...

    c语言经典案例

    实例117 输出两个数中的最大值 156 实例118 判断素数 157 实例119 递归解决年龄问题 158 实例120 递归解决分鱼问题 159 实例121 小数分离 160 实例122 求任意数的n次幂 161 实例123 固定格式输出当前时间 163 实例...

    C语言泛型编程实例教程

    看下面的一个实现交换两个元素内容的函数swap,以整型int为例: void swap(int* i1,int* i2){ int temp; temp = *i1; *i1 = *i2; *i2 = temp; } 当你想交换两个char类型时,你还得重写一个参数类型为char的...

    C++ 排序 projectCpp_排序

    void swap1(float *a, float *b){ //交换两个变量的值 float temp; temp = *a; *a = *b; *b = temp; } void ssort (float *a, int m){ int i, j, index; float elem; for (i=0;i;i++) { elem = *(a+i); ...

    关于JS解构的5种有趣用法

    前言 原文标题:5 Interesting Uses of JavaScript Destructuring ...常见的交互两个变量值的方法都需要借助一个额外的变量,看一个简单的例子: let a = 1; let b = 2; let temp; temp = a; a = b; b = tem

    C程序范例宝典(基础代码详解)

    实例038 不用strcat连接两个字符串 46 实例039 删除字符串中连续字符 47 实例040 字符升序排列 49 实例041 在指定的位置后插入字符串 50 1.7 函数 51 实例042 求字符串中字符的个数 51 实例043 递归...

    最新名企标准通用C++面试题,

    7、实现双向链表删除一个节点P,在节点P后插入一个节点,写出这两个函数。 void DeleteNode(DuNode *p) { p-&gt;prior-&gt;next=p-&gt;next; p-&gt;next-&gt;prior=p-&gt;prior; } void InsertNode(DuNode *p, DuNode *s)//Node "s...

    安装Oracle9i for HP-UX双机笔记

    如果在/tmp 目录下没有400MB 以上的空间,在另一个文件系统 下建立一个/tmp目录,然后设置环境变量TEMP(由Oracle使用)和TMPDIR(由操作系统程序 使用)使其指向这个位置。具体如下: $ mkdir /u03/tmp...

    语言程序设计课后习题答案

    2-16 已知x、y两个变量,写一条简单的if语句,把较小的的值赋给原本值较大的变量。 解: if (x &gt; y) x = y; else // y &gt; x || y == x y = x; 2-17 修改下面这个程序中的错误,改正后它的运行结果是什么? #include ...

    华为编程开发规范与案例

    对某交换类进行计费测试,字冠011对应1号路由、1号子路由,有4个中继群11,12,13,14(都属于1#模块),前后两个群分别构成自环。其中11,13群向为出中继,12,14群向为入中继,对这四个群分别进行计费设置,对出入中继都...

    基于C51单片机的篮球计分器设计.doc

    基于C51单片机的篮球计分器设计 题目要求: 1. 设计一款能够显示篮球比分的记分牌; 2. 通过加分按钮可以给A队,或B队... //中间变量temp,检测到有按键按下时交换A,B两队分数 if(A_add==0) //当检测到A队加分按键按

    数组常见排序

    i++){//i从一开始,因为第一个数已经是排好序的啦 23.for(intj=i;j&gt;0;j--){ 24.if(x[j][j-1]){ 25.inttemp=x[j]; 26.x[j]=x[j-1]; 27.x[j-1]=temp; 28.} 29.} 30.} 31.for(inti:x){ 32.System.out.print(i+""); 33.}...

    [人工智能]模拟退火算法及实践.pdf

    通过交换两个城市的位置得到序列的领域,作为新解,如果温度为0,则转(6); (3).将新解与最优解⽐较,如果新解⼩于最优解,则将新解作为最优解,否则则以Metropolis 准则决定是否接受差解为最优解; (4).如果系统处于...

Global site tag (gtag.js) - Google Analytics