目录
前言--两个数互换
交换数值,我们常常借用第三方空间,比如下面的temp。
int a=1;
int b=2;
//交换a、b
int temp=a;
a=b;
b=temp;
但是在不占用额外空间时,我们也可以用其他方法进行交换。
a = a-b;
b = b+a; //b=b+a=b+(a-b)=a
a = b-a; //a=b-a=a-a=a-(a-b)=b
下面就介绍在不使用额外空间时的多个数的互换。
三个数互换
int a=1; int b=2; int c=3;
//交换a、b、c
//a=b,b=c,c=a
a=a-b;
b=b-c;
c=c+b+a; //c=a
a=c-a; //a=b
b=a-b; //b=c
也可以这样写:
//a=b,b=c,c=a
//先写b
b=b-c;
c=c-a;
a=a+b+c; //a=b
b=a-b; //b=c
c=b-c; //c=a
规律
经过多次尝试,我们发现无论先写谁(先改变谁的值)都有对应的互换写法。
其次,我们找到具有一般规律的写法。
比如交换三个数的第一个例子,b赋给a、c赋给b、a赋值给c。
写法可以分为上、中、下三部分 。上面部分是改变一些变量(a、b)的式子;中间部分仅一行(绿色方框),表示改变最后一个变量(c)的式子,最后一个变量改变后为最终交换的值;下面部分是除最后一个变量外其余变量(a、b)的最终改变式。
如果整个结构以中间部分为分界,我们可以观察到,红线和绿线处有对应关系;上面部分中每一个式子为该变量交换前的值减交换后的值;中间处,最后一个变量为所有变量之和;下面部分中,每行等式左边数的先后顺序(a—b)与上面部分一样,且减号后的数与等式左边的数一致。
写法
这样,我们就可以表示出一个完整的写法。
1.确定好赋值关系:v1、v2、v3...vN = d(v1)、d(v2)、d(v3)...d(vN)
这里我们用d( )表示对应关系,如d(v1)表示要赋值给v1的变量 再如d(a)=b表示b赋给a。
2.先写出要改变的第1个变量(v1),随意定。
3.写出上半部分:
交换前的值减交换后的值
式1: v1=v1-d(v1)
再根据红线规则写出下一式等式左边的变量
式2: d(v1)=d(v1)-d(d(v1))
依次类推......直到N-1式
4.中间部分:
最后一个变量v_Last为所有变量之和
v_Last=v1+v2+v3+...+v_Last
5.下面部分:
等式左边的先后顺序与上半部分一致,再根据绿线规则写出等式右边的减号前的变量,减号后的变量与等式左边的变量一致。
式1: v1=v_Last-v1
式2: d(v1)=v1-d(v1)
依次类推......直到N-1式
6.结束,完成交换。
四个数互换
接下来我们用以上规律写出四个数互换的写法。
int a,b,c,d = 1,2,3,4;
//a、b、c、d = b、c、d、a
//输出:a=2,b=3,c=4,d=1
//写法1:从a开始
a=a-b;
b=b-c;
c=c-d;
d=d+c+b+a;
a=d-a;
b=a-b;
c=b-c;
//写法2:从b开始
b=b-c;
c=c-d;
d=d-a;
a=a+b+c+d;
b=a-b;
c=b-c;
d=c-d;
//写法3:从c开始
c=c-d;
d=d-a;
a=a-b;
b=a+b+c+d;
c=b-c;
d=c-d;
a=d-a;
其他互换顺序也成立。
int a,b,c,d = 1,2,3,4;
//a、b、c、d =d、c、a、b
//输出:a=4,b=3,c=1,d=2
//从c开始
c=c-a;
a=a-d;
d=d-b;
b=a+b+c+d;
c=b-c;
a=c-a;
d=a-d;
更多位数或其他写法可由大家可以自己尝试。
但是目前我只使用第三方交换已经足够,这个方法只是突发奇想罢了。(可能以后有用到的时候)
欢迎各位大神补充与纠错。