算法通关村第十三关黄金挑战——数论问题解析

大家好,我是怒码少年小码。

欧几里得算法

也叫辗转相除法。常常用于求两个数的最大公因数(gcd)。规则:若r是 a / b 的余数,则gcd(a,b) = gcd(b,r)

至于原理可以看这个视频教程:

https://www.bilibili.com/video/BV19r4y127fu/?share_source=copy_web&vd_source=2a3492e7c7e00320005683fe2b41530e

还是没懂可以看这个文字介绍:

https://www.zhihu.com/question/51427771

这里就直接上代码了:

int gcd(int a,int b){
  int k;
  do{
   k=a % b;
   a = b;
   b = k;
  }while(k !=0 )
  return a;
}

素数和合数

素数又称为质数,素数首先要满足大于等于2,并且除了1和它本身之外,不能被任何自然数整除,其他数都是合数。比较特殊的是1即非素数,也非合数。2是唯一的同时为偶数和素数的数字。

如何判断一个正整数为素数

基本的方式是从2开始依次与n取余测试,看看是否出现n%i == 0的情况,如果出现则说明当前的n能被i整除,所以就不是。从2开始遍历一直到n^(1/2)即可。(思考一下为什么?)

public static boolean isPrime(int num) {
     int max = (int)Math.sqrt(num);
     for (int i = 2; i <= max; i++) {
         if (num % i == 0) {
             return false;
         }
     }
     return true;
 }

这个方法的性能不够,n很大时会超时。下面还有一种方式很有效。

埃式筛

如何使用埃式筛判断n之前的数字有多少个质数

基本思想:如果x是质数,那么大于x的xy的倍数 2x. 3x …一定不是质数,可以从这一点入手。

首先,定义一个n大的数组保存有多少个质数。数组初始化全为1,表示每个位置上都是质数。

先选中数字2,2是素数,然后将2的倍数全部排除(在数组里将该位置标记为0)
接着选中数字3,3是素数,然后将3的倍数全部排除
接着选中数字5,5是素数,然后将5的倍数全部排除
接着选择7,11,13一直到n …

最后在统计数组中1的个数就可以了。

public static int countPrimes2(int n) {
    int[] isPrime = new int[n];
    Arrays.fill(isPrime,1);
    int ans = 0;
    for (int i = 2; i < n ;i++){
        if (isPrime[i] == 1){
            ans += 1;
            //开始排除倍数
            if ((long) i * i < n){
                for (int j = i* i ; j < n ; j += i){
                    isPrime[j] = 0;
                }
            }
        }
    }
    return ans;
}

丑数问题

丑数:只包含质因子2、3和5的数。判断一个数是不是丑数。

思路分析:
根据丑数的定义,0和负整数一定不是丑数

当n > 0时,若 n 是丑数,则 n 可以写成 n = 2^a + 3^b + 5^c的形式,其中a,b,c都是非负整数。比如说,当a,b,c都是0时,n = 1
为了判断n 是否满足上述形式,可以对n反复除以2,3,5,直到n 不再包含质因数2,3,5。若剩下的数等于1,则说明n不包含其他质因数,是丑数;否则,说明n包含其他质因数,不是丑数。

public boolean isUgly(int n){
  if(n <= 0){
    return false;
  }
  int[] factors = {2,3,5};
  for(int factor: factors){
    while( n % factor == 0){
    n /= factor;
    }
  }
  return n==1;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
RSA是一种非对称加密算法,由三位科学家Rivest、Shamir和Adleman共同发明,在加密和数字签名领域发挥着重要作用。RSA算法基于数论中的两个重要难题:大整数分解和模幂运算。 RSA算法的核心概念是公钥和私钥。在加密过程中,首先需要生成一对密钥,其中一个是公钥,可以公开给其他人使用,而另一个是私钥,必须保密。通过公钥可以将信息进行加密,而只有使用私钥才能解密。 RSA算法的加密过程如下:选择两个大素数p和q,并计算它们的乘积n=p*q作为所需的大整数。再选择一个与(p-1)*(q-1)互质的正整数e作为公钥,其中1 < e < (p-1)*(q-1)。然后计算d,满足(d*e) mod ((p-1)*(q-1)) = 1,并将d作为私钥。公钥对应着(n, e),私钥对应着(n, d)。 对于明文M,加密后得到密文C,加密过程为C = M^e mod n。解密过程为M = C^d mod n。由于大整数分解问题的复杂性,只有获得私钥才能成功解密,保护了通信的安全性。 RSA算法广泛应用于计算机网络和电子商务中,例如在网站上进行数据传输过程中,使用RSA加密算法保护数据的机密性和完整性,确保数据不被窃取或篡改。 需要注意的是,尽管RSA算法在安全性上相对较好,但其加解密过程消耗较大的计算资源,在处理大量数据时效率可能较低。因此,在实际应用中,常常将RSA与其他加密算法结合使用,以平衡安全性和效率的要求。 总之,RSA算法作为一种非对称加密算法,通过公钥和私钥的配对实现信息的加密和解密。它在数据安全领域的应用广泛,为保护通信和数据的安全做出了重要贡献。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值