题目:1. 分别随机输入两个不多于5位的正整数,要求:①分别求出这两个整数是几位数;②分别逆序打印出这两个整数的各位数字;③计算这两个整数的最小公倍数和最大公约数;④分别判断这两个数是否为素数。请编写出符合题目要求的程序。
因为题目没有说明要完成要求的顺序,所以我将逆序打印、最大公约数、最小公倍数、几位数放在后面,怕逆序打印、最大公约数最小公倍数会改变这两个数(假设为 a 和 b 吧)——因此,我先完成判断是否为素数。
要求 4 ——素数判断:
素数就是一个除1还有本身之外都不能整除的数,因此我们可以从定义入手。代码如下:
for(int d = 2; d <= a; d++) 用 for 循环实现从 2 除到 a
{
if( a % d == 0) 当能整除的时候跳出循环
break;
}
if( a == d) 若 a 与 d 相等,则说明从 2 到 (a - 1)都没有能整除的
printf(" a 为素数");
else
printf(" a 不是素数");
b 的判断与 a 一样
当然我们可以优化一下,首先偶数除二之外不是素数,而且 a 其实都可以因式分解为两个小于等于根号 a 的数,因此可以优化循环部分。代码如下:
for( int d = 2; d <= sqrt(a); d += 2)
{ // 这里的sqrt是库函数里的,可以求括号里 a 的开方,
if( a == d) // 不过 sqrt 要引用头文件<math.h>
break;
}
if( a == d)
printf(" a 为素数");
else
printf(" a 不是素数");
这样就可以判断 a 和 b 是不是素数了。
在逆序打印前,为防止逆序和求最大公约时改变了a 、b 的值,先“复制粘贴”几个a 和 b。代码如下:
int A = a, B = b; int C = a, D = b; int E = A,F = B;
要求2——逆序打印:
我们逆序打印时可以先打印个位,再打印十位......以此类推。先举个例子——要逆序打印234,就要打印出4 3 2 ,又如999 ,就要打印 9 9 9。这时可以发现每次打印的数都不超过10,因此我们可以联系到要有循环且循环体与 10 有关。直接代码如下吧:
while(a != 0)
{
printf("%d",a%10);
a = a / 10;
}
b 的逆序与 a 一样
首先 printf("%d",a%10); 是来打印此时 a 的最后一位数的。接下来要打印倒数第二位,此时要打印倒数第二位数要先把它移到最后一位——把 a 除以 10 就可以解决了。然后一直循环直到全部打印完,当打印完后 a 的值一定只剩个位数,这时除以 10 之后就为 0 了,因此循环的条件就是 a!=0。
要求3——求 a 和 b 的最大公约数和最小公倍数:
这里我求公约数时采用了辗转相除法,我简单讲下辗转相除法的功能——假设 a 除以 b 等于 k 余 r,即 a / b = k ------r。如果我们想求 a 和 b 的最小公约数,那么辗转相除法则告诉我们 a、b的最小公约数 等于 b、r 的最小公约数,以此类推直到新的余数 c 为0,此时的 新的除数B就是 a、b的最小公约数。若想详细了解辗转相除法可以去网上查,这里不多解释。
while(B) //这里我用前面定义的 A 和 B
{
c=A%B;
//printf("%d",c);
A=B; //当余数c为0的时候,A 和B交换了一次,所以最大公约数
B=c; //是A,而不是B。因此打印A
}
printf("a和b的最大公约数为:%d \n",A);
当最大公约数求出来的,最小公倍数就简单多了,直接用数学公式:最小公倍数 = 两数乘积 / 最大公约数。当然这里已经不能再用 A 和 B 了,因为求最大公约数之后,A 、B的值变了。代码如下:
int m = (E * F) / A; //这里用前面先定义好的E 、F
printf("则,a 和 b 的最小公倍数 m = %d \n",m);
要求1——求 a 和 b 为几位数:
当时我做到这里时,不知道为何感觉这个和逆序打印有点像。同样举例一下,234 为 3 位数,而234只能被10除 3次,除 3次后变为0;又如9999为 4 位数,而9999只能被 10除以 4次,除 4次后变为0.......因此我们只要每次除以 10时,计数一下,最后打印计数就可以了。代码如下:
int q=0;
while(C>0)
{
C = C/10;
q++;
}
printf("a为%d位数\n",q);
b 的求法和 a 一样。
此时所有要求都完成了只要完成适当拼接就可以。
全部代码如下:
#include <stdio.h>
int main()
{
int a,b,j,d,c; //输入 a,b
scanf("%d%d",&a,&b); //判断 a 和 b 是否为 素数(除了 1 和 自己 之外的其他数都不能整除,即 a 除以从 2 到 ( a - 1) 的余数都不为 0 )
for(d=2;d<=a;d++) //利用 for 循环 从 2 到 a 进行整除
{
if(a%d==0) break; //当找到了一个数 d 能整除 a ,则跳出循环
}
if(a==d) printf("a是素数\n"); //对 d 是否等于 a 进行判断
else printf("a不是素数\n"); //若 d != a ,即从 2 到 ( a - 1)可以找到一个数整除 a
for(j=2;j<=b;j++) //判断 b 是否为素数的方法与 a 一样
{
if(b%j==0) break;
}
if(b==j) printf("b是素数\n");
else printf("b不是素数\n");
int A = a, B = b; //为了防止逆序打印后 a 和 b 的值改变,将 a 和 b 的值赋给 A 和 B,这样就可以利用 A 和 B 求出 a 和 b 的最大公约数
int C = a, D = b;
int E = A,F = B;
printf("逆序打印a:>\n"); //逆序打印 a
while (a != 0)
{
printf(" %d \n", a % 10);
a /= 10;
}
printf("逆序打印b:>\n"); //逆序打印 b
while (b != 0)
{
printf(" %d \n", b % 10);
b /= 10;
}
while(B) //开始求最大公约数 (辗转相除法)
{
c=A%B;
//printf("%d",c);
A=B;
B=c;
}
printf("a和b的最大公约数为:%d \n",A);
int m = (E * F) / A;
printf("则,a 和 b 的最小公倍数 m = %d \n",m);
//开始求 a 和 b 为几位数
int q=0,w=0;
while(C>0)
{
C = C/10;
q++;
}
printf("a为%d位数\n",q);
while(D>0)
{
D = D/10;
w++;
}
printf("b为%d位数\n",w);
return 0;
}
最后,我成功进入学校的软件应用技术实验室啦。所以今天我把第一题发了出来(考核时间已经结束了,发出来是没事的),把题分享给大家,顺便也把题再讲给自己听一次吧!