Python:CRT中国剩余定理的简单实现

简单实现中国剩余定理,仅适用于模数两两互素的情形,否则跳出

m序列和a序列均采用逐个输入的方式

以字母q作为每个序列最后一个元素作为结束符号

import math

def modinv(M,m):
    x1,x2,x3=1,0,M
    y1,y2,y3=0,1,m
    while y3!=0:
        q=x3//y3
        t1,t2,t3=x1-q*y1,x2-q*y2,x3-q*y3
        x1,x2,x3=y1,y2,y3
        y1,y2,y3=t1,t2,t3
    return x1%m

endstr='q'
mstr=''
i=1
print('m'+str(i)+'=',end='')
for line in iter(input,endstr):
    mstr+=line+' '
    i+=1
    print('m'+str(i)+'=',end='')
mlist=mstr.split(" ")
del mlist[-1]
mlist=[int(mlist[i]) for i in range(len(mlist))]

for i in range(len(mlist)-1):
    j=i+1
    while j<len(mlist):
        if math.gcd(mlist[i], mlist[j])!=1:
            print('不能直接利用中国剩余定理')
            break
        else:
            j=j+1
    if j!=len(mlist):
        break
    elif i==len(mlist)-2:
        m=1
        for i in range(len(mlist)):
            m=m*mlist[i]
        astr=''
        s=1
        print('a'+str(s)+'=',end='')
        for line in iter(input,endstr):
            astr+=line+' '
            s+=1
            print('a'+str(s)+'=',end='')
        alist=astr.split(" ")
        del alist[-1]
        alist=[int(alist[i]) for i in range(len(alist))]
        
        x=0
        for i in range(len(mlist)):
            x=int(x+alist[i]*(m//mlist[i])*modinv(m//mlist[i], mlist[i]))
        print('x ≡',x%m,'\n (mod',m,')')

序列的输入采用以单个回车作为分隔的方式(适用于ctrl+c

import math

def modinv(M,m):
    x1,x2,x3=1,0,M
    y1,y2,y3=0,1,m
    while y3!=0:
        q=x3//y3
        t1,t2,t3=x1-q*y1,x2-q*y2,x3-q*y3
        x1,x2,x3=y1,y2,y3
        y1,y2,y3=t1,t2,t3
    return x1%m

mstr=input('m:')
mlist=mstr.splitlines()
mlist=[int(mlist[i]) for i in range(len(mlist))]

for i in range(len(mlist)-1):
    j=i+1
    while j<len(mlist):
        if math.gcd(mlist[i], mlist[j])!=1:
            print('不能直接利用中国剩余定理')
            break
        else:
            j=j+1
    if j!=len(mlist):
        break
    elif i==len(mlist)-2:
        m=1
        for i in range(len(mlist)):
            m=m*mlist[i]
        
        astr=input('a:')
        alist=astr.splitlines()
        alist=[int(alist[i]) for i in range(len(alist))]
        
        x=0
        for i in range(len(mlist)):
            x=int(x+alist[i]*(m//mlist[i])*modinv(m//mlist[i], mlist[i]))
        print('x ≡',x%m,'\n (mod',m,')')

以上两种方式主要区别在于输入的方法,其他部分无差,算法的实现重点在于实现大整数的模逆运算和理解扩展欧几里得算法

(总不能一个个试数字直到满足条件吧

也可以尝试更方便快捷的文件输入方式

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值