赞
踩
2023年湖北省专升本考试已经在5月7日举行完毕。不少同学告诉学长今年的题目很难,那么接下来我们一起来看看来自湖北省一所公办院校的题目吧。
题目:
打印出一个完数的所有因子(根据学弟的回忆是这样的,但是题目应该不太完整,因此我在这里将完整题目的几种可能全部罗列出来,供大家学习参考)
对于完数的定义,百度百科的回答是:
完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。如果一个数恰好等于它的因子之和,则称该数为“完全数”。第一个完全数是6,第二个完全数是28,第三个完全数是496,后面的完全数还有8128、33550336等等。
1.找出0~100以内所有完数,并打印出它的所有因子
- //1.找出0~100以内所有完数,并打印出它的所有因子
-
- //本题使用暴力枚举法,暴力枚举发是最常用的一种算法,也是解决一些不太复杂问题的思想最简洁的方法
- #include<stdio.h>
- int main(){
- for(int i=0;i<101;i++){ //定义外循环,用来模拟0~100之间的所有数字
- int n = 0; //定义变量n用来在给数组元素赋值时负责使数组下标累增,且在打印数组已赋值元素时起到一个界定数组下标的作用(即有多少数组元素被赋值)
-
- int total = 0; //变量total是用来统计一个数所有因子之和的(除了这个数本身),因子之和是判断一个数是否为完数的一个重要条件
-
- int factor[30] = {0}; //定义一个数组,用来临时存放一个数的所有因子
-
- for(int j=1;j<100;j++){ //定义内循环,用来做除数,外循环的速度比内循环慢,因此内循环为除数可以使外循环的每一个数都将内循环的每一个数都除一遍,这就是
- //暴力枚举法的内涵,当然该方法可以被简化,以避免一些不必要的计算,例如我们知道一个数除以大于它的数,一定是除不尽的,因此我们
- //可以在循环上做手脚,避免被除数去除大于它本身的除数,这个就留给各位小可爱自己思考吧,看你们是否能够将该代码进行优化。
-
- if(i % j == 0 && i != j){ //if条件句,用来判断除数是不是被除数的因子,因为我们知道,一个数能够被另外一个数整除,那么这个数的除数就是这个数的一个因子
- //重要的是,这个数本身也是它本身的因子,而完数定义是,除它本身以外所有因子之和,因此我们要避免掉这种情况,于是我令i!=j
-
- total += j; //累加计算符合条件的因子之和
-
- factor[n] = j; //将符合条键的因子,存入数组中,注意我定义数组的位置,是定义在外循环内的,这样可以帮我们在外循环每次循环后内循环开始之前将数组
- //重新初始化,以达到清除数组元素值的,重新为存储下一个完数的因子做准备。你也可以看到我的变量n和变量total都是定义在外循环之内的
- //合理的使用,多层循环的特点可以,为我们编写程序带来便利,如果我将数组定义在外循环之外,那么可想而知,我在每次外循环开始之前
- //又要重新定义一遍数组,或者用for循环清空数组元素值。或者我定义在内循环里面,那么将会直接导致程序出错,得不到正确的答案。
-
- n++; //用来,做累增,以便为数组下一个元素赋值,和上面的数组定义是一个道理
- }
- if(total == i){ //这是判断一个数是否为完数的第二个必要条件,因子之和要等于这个数本身
-
- printf("%d是一个完数,其因子为:",i); //打印输出,不写换行符是因为为了去衔接后面for循环循环输出它的因子
-
- for(int i=0;i<n;i++){ //i<n是因为,我们在上面只进行了n次为数组元素赋值,换一种说法也就是这个数组只有n个元素得到了赋值
-
- printf("%d ",factor[i]); //打印数组元素
- }
- printf("\n"); //换行符写在所有打印之后,能够起到一个每次内循环结束之后,条件满足时换行,也就是说保证下一个完数和它的因子不和上一个完数和他的因子黏在一起
- }
- }
- return 0;
- }
2.输入一个数,判断其是否为完数,如果是,则打印出它的所有因此,若不是打印这个数不是一个完数。
- //2.输入一个数,判断其是否为完数,如果是,则打印出它的所有因此,若不是打印这个数不是一个完数。
- #include<stdio.h>
- int isfactor(int x,int *factor,int *point){ //函数定义在开头避免在主函数中再次声明,函数拥有三个形参,一个int类型的普通变量,两个int类型的指针变量
- int total = 0; //total用来统计这个数的所有因子和(除它本身以外)
- int flag = 0; //flag用来统计数组中有几个元素被赋值了
- for(int i=1;i<x;i++){ //for循环用来使小于这个数的所有数除一遍这个数,上面的题目中我们说过了,一个比它大的数,不可能使这个数的因子,因此我们for循环
- //结束的条件就是这个数的除数要小于等于这个数,当然因为完数是等于除它本身以外所有因子之和,那么我们就要将这个数它本身拔出在外
- //所以我写的是小于x而不是小于等于x,x是主函数中实参num传递过来的数据值可以认为x=num,i的初值为1,不为0是因为0不能做除数,这个
- //规定是刻在计算机DNA里面的,我在刚写这个程序的时候就在这上面吃了很大的亏,结果是错的,但是不给我报错信息,我只能一步一步排查
- //最后才意识到这个问题。
-
- if(x % i == 0){ //if条件句用来判断i是否为x的因子
- total += i; //total用来统计因子之和
- *factor++ = i; //这个指针变量是用来接收主函数中的数组名,数组名是地址,指针也是地址,因此形参指针与数组名指向了同一个地址,该地址即数组这个盒
- //子的钥匙。
- flag++; //该变量用来记录数组中有多少个元素被赋值
- }
- }
- if(total == x){ //该条件句写在for循环之后是为了确保x被每一个小于它的数都除了一遍,这样得到的total值就是所有因子之和,不会遗漏,另外这是判断一个数
- //是否为完数的必要条件之一
-
- *point = flag; //形参指针point接收的是主函数中变量flag的地址,因此指针point指向了flag变量的地址,我们改变指针的值即这个地址里面存放的数据为函数
- //isfactor中的变量flag的值,这样相当于间接的给主函数中变量flag重新赋值,这样做的目的是因为虽然一个函数可以有多个返回值,但是我们
- //无法将所有返回值的值都获取到,因此只能只用指针传值的方式解决该问题,将flag的值提前传递给主函数中的flag
-
- return x; //条件成立的情况下,将x作为返回值返回给主函数中调用它的函数。将return语句写在if条件句的最后是因为,当函数遇到了return语句就会认为该函数
- //已经结束,便不会在执行后面的语句了。
- }
- return 0; //当上面的if条件不满足时,返回值为0
- }
-
- int main(){
- int num = 0; //变量num是用来获取用户在键盘上输入的数据
- int fator[30] = {0}; //定义一个int类型的数组,用来临时存储一个数的所有因子
- int flag = 0; //变量flag用来获取一个完数的因子个数,即在isfactor函数中,为数组中多少个元素赋了值
- printf("please input a number:"); //提示用户输入数据
- scanf("%d",&num); //接收键盘上输入的数据
- int result = isfactor(num,fator,&flag); //调用函数isfactor,并传入三个实参,分别为num的数值,数组名factor,变量flag的地址,并将函数的返回值赋值给
- //变量result
- if(result){ //判断result拿到的返回值是否为真(非0即真),如果不是真就打印这个数不是一个完数
- printf("%d是一个完数,其因子为:",num); //如果为真,那么打印这个数是一个完数
- for(int i=0;i<flag;i++){ //利用for循环将数组中存放的这个完数的因子打印出来,flag上面解释了,利用了指针的特点做了暗传值
- printf("%d ",fator[i]); //循环打印因子
- }
- }else{
- printf("%d不是一个完数",num);
- }
- return 0;
- }
该题目的代码还可以继续完善为一个程序,在其中添加一个循环,一达到用户输入一个数就判断一次的目的,而不是像现在这样想要判断一个数是不是完数需要每次判断之前先执行一遍程序,这样即浪费时间又浪费内存,想法提供给大家了,又想完善的同学大家可以自己动手写一写哦,不会的可以私信博主要完整代码呀。
上述两个题目,都是关于完数的题目,分别从两个不同的方面出发,一个是指定范围查找该范围内的完数、完数个数和完数所有因子,一个是给定一个数判断该数是否为完数,如果是则打印改完数的所有因子,若不是则提示不是完数。其实学长也是看了许多其他博客,但是发现写的方法都比较复杂难懂,且解释过于术语化,或者基本没有代码解释,因此学长利用自己对C语言的了解编写了这两个程序供大家参考。该代码文章为原创代码文章,若转发使用请标明出处,谢谢。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。