C语言教程:觉得经典的算法
文章类别:
C语言程序设计 | 发表日期:2010-11-3 9:35:05
1:交换算法 交换a,b 设置中间变量t {t=a,a=b,b=t}
2:排序算法 a,b,c大到小排序
if(a<b) {t=a,a=b,b=t};
if(a<c) {t=a,a=c,c=t};
if(b<c) {t=b,b=c,c=t};
3:3个数求最大值 可以用交换,然后输出最大的,还有一种简单点的
max=a>b?a:b
if(c>a) max=c
4:多个数排序(10个)可以用冒泡法(书上有),这里介绍一种不同的
for(i=0;i<+9;i++)
for(j=0;j<=9;j++)
if(a[i]>a[j])
{t=a[i];a[i]=a[j];a[j]=t;}
5:倒着输出法
for(i=0,j=9;i<j;i++;j--)
{t=a[i];
a[i]=a[j];
a[j]=t;
}
6:移位算法,意思是1 2 3 4 5 左移一位变成2 3 4 5 1
右移一位变成5 1 2 3 4
左:t=a[0]/*把第一个数提出来*/
for(i=0;i<=4;i++)
a[i-1]=a[i]; /*把a[i]赋值个前一个数*/
a[4]=t; /*最后一个数*/
右:
t=a[4]; /*把最后一个数提出来*/
for(i=3;i>=0;i--)
a[i+1]=a[i];
a[0]=t;
两个数交换,不设新变量
a=a+b;
b=a-b;
a=a-b;
#define j 4//数组元素数
int a[j]
for(i=0;i<j;i++)
a[i]=a[i]+a[j-i];
a[j-i]=a[i]-a[j-i];
a[i]=a[i]-a[j-i]
j--
//活用5楼算法 颠倒数组元素值
交换两个数字的顺序
cha(int a,int b)
{a=a+b;
b=a-b;
a=a-b;
}
求3个数a,b,c中的最大:
max=a>b?(a>c?a:c):(b>c?b:c)
int a,b;
a=a+b;
b=a-b;
a=a-b;
这样可能会出错
比如在32位环境下int型占4个字节也就是a最大为2147438647
16位环境下int型占2个字节 最大值为32767
a+b可能会超出这个范围
无临时变量的交换两数函数 漏洞揭密
有一个巧妙的数值swap函数是这样写的:
void swap (int& a, int& b)
{
a=a+b; //防止溢出,漏洞1。
b=a-b;
a=a-b;
}
之所以要这样而不用中间变量,据说是因为原来的计算机内存容量小,所以能节约的地方要尽量节约。具体的原因我这里不想去考证了,我要说的是,在这个看似简单而巧妙的函数中暗藏着危机。
这个危机是由形参中变量的引用带来的。我们知道C++中引入的“引用”,实际上就是变量的别名,也就是说允许一个内存单元对N个变量名。那么对该swap函数的调用:
swap (a, a); //漏洞2。
会造成函数作如下的解释:
a=a+a;
a=a-a;
a=a-a;
很显然,这样不会得到正确的结果。我们想要的结果本来应该是交换后结果不变(采用中间变量的方法得到的结果就是如此),但是实际的结果是a=0?很明显,我们采用这个函数的前提是a和b不能是同一个变量。
……