今天散步时偶然想起了之前写的辗转相除法求两个数最大公约数的代码,突然想到了求一组数的最大公约数的方法,基本代码如下
l=list(eval(input("请输入一组数\n")))
#l1=l #求最小公倍数时要用到
l=sorted(l) #给这组数排序
while l[-2]!=0: #下面仔细讲讲吧,防止遗忘
if 0 in l:
l.pop(l.index(0))
l.insert(0,max(l)%min(l))
l.pop(l.index(max(l)))
print(l[-1])
l=list(eval(input("请输入一组数\n")))
l1=l
l=sorted(l)
while len(l)!=1:
if (max(l)%min(l))!=0:
l.insert(0,max(l)%min(l))
l.pop(l.index(max(l)))
也可以这样写
辗转相除法百科:欧几里得算法_百度百科
个人理解的辗转相除法的核心其实就是把一个数看作是n个最大公约数的倍数,通过求余的方式一步步把倍数缩小,当不能再缩小倍数时,就得到了最大公约数。
一组数和两个数核心思想是通用的,只不过需要缩小这组数里所有的数。具体方法如下:
1.把最大的数对最小数求余(原因是最小数是离最大公约数最近的那个数)
2.把余数加到列表,去掉最大数(相当于用这次运算的余数替代最大数)
3.重复上两个步骤就行了,不过在程序中实现需要去掉0防止对0求余报错
21,30,12,24 这组数的计算过程是这样的
对倒数第二个数进行检测,为零的时候表示已经计算完成了,最后一个数求是要求的最大公约数。
其实想写一下数学推导过程的,但是想到自己写得并不严谨所以还是算了吧。
如果要对负数求最大公约数的话,可以遍历列表,把负数替换为正数
要求最小公倍数的话,就加上这些代码,并且把基础代码第二行取消注释:
d=l[-1]
for i in l1:
d=d*(i/l[-1])
print(d)
最后加上计算结果:
请输入一组数
21,30,15,24
3
请输入一组数
1,1,1,1,1,1,1,1,1
1
请输入一组数
0,0,0,0,0
0
请输入一组数
4,16,20,256,800,1024
4
请输入一组数
4334,4134,654,39321,380148,4834914894
1
请输入一组数
90,80
10