迭代算法
最经典的迭代算法是欧几里德算法,用于计算两个整数a, b(假设a>b)的最大公约数。其计算原理依赖于下面的定理:
定理:gcd (a, b) = gcd (b, a mod b)
证明:a可以表示成a = kb + r,则r = a mod b。假设d是a,b的一个公约数,则有 a%d==0,b%d==0,而r = a - kb,因此r%d==0 ,因此d是(b,a mod b)的公约数
同理,假设d 是(b,a mod b)的公约数,则 b%d==0,r%d==0 ,但是a = kb +r ,因此d也是(a,b)的公约数。
所以我们得到(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等。
第一种求解
欧几里德算法又叫辗转相除法,它是一个反复迭代执行,直到余数等于0停止的步骤,这实际上是一个循环结构。其算法用C语言描述为:
int gcd(int a, int b)/*欧几里德算法求a,b的最大公约数*/
{
if (a<=0 || b<=0)/*预防错误*/
return 0;
int temp;//迭代临时变量
while (b > 0)/*b总是表示较小的那个数,若不是则交换a,b的值*/
{
temp = a % b;/*迭代关系式*/
a = b;
b = temp;
}
return a;//此时返回的值为a,也就是最大公约数
}
从上面的程序我们可以看到a,b是迭代变量,迭代关系是temp = a % b;根据迭代关系我们可以由旧值推出新值,然后循环执a = b; b = temp;直到迭代过程结束(余数为0)。
第二种求解
1.选出a,b中最小的一个数字放到c中
2.分别用a,b对c求余数,即看是否能被c整除
3.直到a,b同时都能被c整除
4.如不能整除,c– (c的值减一) 继续从2开始执行
5.也就是说该循环的判断条件为 a,b能否同时被c整除,只要有一个数不能被c整除,循环继续执行
while(1){ //设置一个循环,为了避免死循环,也可以使用for
scanf("%d %d",&a,&b);
c = (a>b)?b:a; //进行交换,保证c为最小值
while((a%c != 0) || (b%c != 0))//进行迭代求解,让c为最小公倍数
/*也可以写成
for(;c>0;c--)
if(a%c==0&&b%c==0) printf("%d",c)
*/
{
c--;
}
printf("最大公约数为: %d \n",c);
}
补充:
求解最小公倍数
用a*b/c(c为最大公约数)求解就可以得到最小公倍数
交换两值方法
void exchange1(int a,int b){
int temp;
temp=a;
a=b;
b=temp;
}
void exchange2(int a,int b){
a = a + b;
b = a - b;
a = a + b;
}
void exchange3(int a,int b){
a = a ^ b;
b = a ^ b;
a = a ^ b;
}