C++中如何读取一个数的位数_C++完整代码 素数、水仙花数、完数、斐波那契数列、丑数...

大纲

  • 素数:定义、枚举法求解、枚举法优化、埃氏筛求解、欧拉筛求解
  • 水仙花数:定义、水仙花数判断、n位自幂数判断
  • 完数:定义、完数判断
  • 斐波那契数列:定义、打表法、递归求解、通项公式求解
  • 丑数:定义、判断是否为丑数、输出丑数序列、输出第n个丑数的优化算法

素数

定义

  • 素数:一个数的因数只有1和其本身的数,又叫质数
  • eg:7=1 * 7,是素数;8=1 * 8=2 * 4,不是素数。

枚举法求解

  • 其因素只有1和其本身,所以从2~n-1,遍历,若有整除的情况,便不是素数。
#include

枚举法优化

  • IsPrimeNumber函数中,for循环从2~n-1,现可缩小范围。

de264882df1f2b7f9a5db8ae7c3897f1.png
  • 上限变为n/2:因数分解,可得n=1 * n=2 * n/2=......可见其较大的因素,只能从n到n/2、n/3。
  • 上限变为
    :因素分解,最初为1*n,最终为
#include

埃氏筛求素数

  • 算法分析:一个素数的2倍、3倍......等都一定不是素数,因此从小到大依次向上筛选,直到将是素数的倍数全都设为1。
  • 时间复杂度O(nloglogn)
  • 求出1000000以内的素数并且输出前n个素数:
#include

欧拉筛求素数

  • 欧拉筛法的原理同埃氏筛法,只不过多了一个判断删除的过程。首先,任何合数都能表示成多个素数的积。所以,任何的合数肯定有一个最小质因子。我们通过这个最小质因子就可以判断什么时候不用继续筛下去了。当i是prime[j]的整数倍时(i % prime[j] == 0),iprime[j+1]肯定被筛过,跳出循环。因为i可以看做prime[j]某个数, iprime[j+1]就可以看做 prime[j]某个数prime[j+1] 。而 prime[j] 必定小于 prime[j+1],所以 iprime[j+1] 必定已经被 prime[j]*某个数 筛掉,就不用再做了。
  • 求出1000000以内的素数并且输出前n个素数:参考资料
#include

水仙花数

定义

  • 水仙花数:又叫超完全数字不变数,是指一个三位数,每位数字的立方和等于该数。
  • 严格意义上,水仙花数必须是三位数,因为水仙花数数是三位自幂数
  • 自幂数是指一个 n 位数,它的每个位上的数字的 n 次幂之和等于它本身。
  • 自幂数包括:独身数、水仙花数、四叶玫瑰数、五角星数、六合数、北斗七星数、八仙数、九九重阳数、十全十美数。(不存在两位自幂数)

水仙花数判断代码

#include

n位自幂数判断代码

#include 

完数

定义

  • 完数:所有真因子(除了自身以外的因数)之和等于其本身的数,又叫完备数
  • eg:6=1+2+3;1、2、3是6的所有真因子,6是完数。

判断完数代码

bool 

斐波那契数列

定义

  • 斐波那契数列:又叫兔子数列,规定F(1)=1,F(2)=1,F(n)=F(n-1)+F(n-2)(n>=3)。

利用数组求解(打表法)

  • 已知每一项是前两项之和,所以可用数组存放起来。
#include

递归求解

long 

通项公式求解

  • 求解通项公式过程

已知递归关系式:

为了化简解,可以引入额外项f(0)=0。其特征方程式,求得根如下:

由于

,这样递推式的解是

为求和

,求解下面两个联立方程:

求得:

所以,

  • 代码实现
long 

丑数

定义

  • 丑数:不能被2,3,5以外的其他素数整除的数。
  • 从小到大的丑数:1,2,3,4,5,6,8,9,10,12,15,…

判断一个数是否为丑数

bool 

输出丑数序列

  • 这是最简单的输出方法,但是后面很多不是丑数的也要用isUglyNum()函数一直计算。
void 

输出第n个丑数,优化算法

  • 我们可知丑数都是在原有丑数的基础上* 2、* 3、* 5得到的。利用此特性可取新生成的最小值作为新丑数。
int 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值