大数问题(循环求余/快速幂求余/快速幂问题)

1.大数求余问题

在仅使用int32类型存储的前提下,正确计算 x a x^a xa p p p的求余( x a x^a%p xa)的值。
P.S. 虽然在Python中不会涉及到大数问题(Python中没有int32类型,若要使用32位整型,需要x = x & 0xffffffff),但也在此记录下。

解题思路

首先,我们有3个余数定理:

  1. ( a + b ) % c = ( a % c + b % c ) % c (a+b)\%c=(a\%c+b\%c)\%c (a+b)%c=(a%c+b%c)%c
  2. a % c = ( a % c ) % c a\%c=(a\%c)\%c a%c=(a%c)%c
  3. ( a b ) % c = [ ( a % c ) ( b % c ) ] % c (ab)\%c=[(a\%c)(b\%c)]\%c (ab)%c=[(a%c)(b%c)]%c
1.1循环求余 O ( n ) O(n) O(n)

定理3我们可以推知:
x a % p = [ ( x a − 1 % p ) ( x % p ) ] % p = [ ( x a − 1 % p ) x ] % p x^{a}\%p=[(x^{a-1}\%p)(x\%p)]\%p=[(x^{a-1}\%p)x]\%p xa%p=[(xa1%p)(x%p)]%p=[(xa1%p)x]%p
由此,我们可以利用循环操作依次求得 x 1 , x 2 , ⋯   , x a x^1,x^2,\cdots,x^a x1,x2,,xa p p p的余数,保证每轮中间求得的余数都在32位整数范围内。

def remainder(x,a,p):
	"""
	rem = x^a % p
	"""
	rem = 1
	for _ in range(a):
		rem = (rem * x) % p
	return rem
1.2.快速幂求余 O ( log ⁡ n ) O(\log n) O(logn)

定理3可知:
x a % p = ( x 2 ) a / 2 % p = ( x 2 % p ) a / 2 % p x^a\%p=(x^2)^{a/2}\%p=(x^2\%p)^{a/2}\%p xa%p=(x2)a/2%p=(x2%p)a/2%p
又由于 a a a为奇数时 a / 2 a/2 a/2不为整数,故奇偶分开计算:
x a % p = { ( x 2 % p ) a / 2 % p ,     a 为 偶 数 [ ( x % p ) ( x a − 1 % p ) ] % p = [ x ( x 2 % p ) a / / 2 ] % p ,     a 为 奇 数 x^a\%p=\left\{ \begin{aligned} &(x^2\%p)^{a/2}\%p,~~~a为偶数\\ &[(x\%p)(x^{a-1}\%p)]\%p=[x(x^2\%p)^{a//2}]\%p,~~~a为奇数\\ \end{aligned} \right. xa%p={(x2%p)a/2%p,   a[(x%p)(xa1%p)]%p=[x(x2%p)a//2]%p,   a

def remainder(x,a,p):
	"""
	rem = x^a % p
	"""
	rem = 1
	while a:
		if a & 1: rem = (rem * x) % p
		x = x ** 2 % p
		a //= 2
	return rem

2.快速幂问题

快速求解 x n x^n xn

解题思路

设函数 f ( x , n ) f(x,n) f(x,n)求解 x a x^a xa,我们可以知道: x a = ( x a / 2 ) 2 x^a=(x^{a/2})^2 xa=(xa/2)2,则:
f ( x , n ) = f ( x , n / 2 ) × f ( x , n / 2 ) f(x,n)=f(x,n/2)\times f(x,n/2) f(x,n)=f(x,n/2)×f(x,n/2)
又注意到 n n n为奇数时 n / 2 n/2 n/2不为整数,故有:

f ( x , n ) = { f ( x , n / 2 ) × f ( x , n / 2 ) ,     n 为 偶 数 f ( x , n − 1 ) × x ,     n 为 奇 数 f(x,n)=\left\{ \begin{aligned} &f(x,n/2)\times f(x,n/2),~~~n为偶数\\ &f(x,n-1)\times x,~~~n为奇数 \end{aligned} \right. f(x,n)={f(x,n/2)×f(x,n/2),   nf(x,n1)×x   n

  • 递归基: n = 0 n=0 n=0时,返回1; n = − 1 n=-1 n=1时,返回 1 / x 1/x 1/x
  • 依据公式进行尾递归即可
def myPow(x,n):
	"""
	res = x^n
	"""
	if n == 0: return 1
	if n == -1: return 1/x
	if x & 1 == 0:
		tmp = myPow(x,n//2)
		return tmp*tmp
	else:
		return myPow(x,n-1)*x
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目说明】 1.项目代码均经过功能验证ok,确保稳定可靠运行。欢迎下载食用体验! 2.主要针对各个计算机相关专业,包括计算机科学、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师、企业员工。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。在使用过程中,如有问题或建议,请及时沟通。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈! 【资源介绍】 数据结构课设-基于C++和QT实现的快速幂大数计算器源码含设计报告.zip 1 实验内容与要求 3 1.1 问题描述 3 1.2基本要求 3 1.3实现提示 4 1.4 运行结果要求及考核要求 4 2 设计思路 5 2.1 基本思路 5 2.1.1 问题分析 5 2.1.2 加法设计 6 2.1.3 减法设计 7 2.1.4 乘法设计 9 2.1.5 除法设计 9 2.1.6 指数设计 10 2.2 类的设计 11 2.2.1 链表类的设计 11 2.2.2 页面类的设计 13 2.3 额外要求的设计 13 2.3.1 计时功能的实现 13 2.3.2 正则表达式判定输入和去除前导零的实现 14 3 调试分析及测试 14 3.1 调试中的错误 15 3.2 测试分析 15 3.2.1 输入各情况测试 15 3.2.2 加法各种情况测试 17 3.2.3 减法各种情况测试 22 3.2.4 乘法各种情况测试 26 3.2.5 指数各种情况测试 27 3.2.6 文件读写各种情况测试 29 4 课程设计总结 29

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值