如何从浮点列表中获取python中作为整数的最大公约数?

2024-06-28 22:14:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一张花车的清单

l1 = [10.0, 50.0, 100.0]
l2 = [0.1, 0.5, 1.0]
l3 = [20.0, 100.0, 200.0]

所有人都应返回:

i = [1, 5, 10]

以较小的整数作为基数乘数,得到整数的最有效方法是什么?或者是它们的倍数,如果不可能的话

例如:

n1 = [0.2, 0.3, 0.6]

应该回来

i = [2, 3, 6]

 n2 = [1424.56, 2136.84, 4985.96]

应返回:

 i = [ 2, 3, 7] # 712.28 = 1

我使用的是value / min(l1),但它不适用于第二种情况和第三种情况


Tags: 方法l1value情况整数min基数l3
2条回答

您可以将所有数字转换为整数,然后将每个数除以它们的greatest common divisor (GCD)。避免使用浮点数是一个好主意,因为它们无法准确地表示许多小数。 fractions模块非常适合这一点:它可以处理小数和有理数,如1/3和2/7

#!/usr/bin/env python3

from fractions import Fraction
from functools import reduce
from math import gcd

def lcm(a, b):
    return a * b // gcd(a, b)

def common_integer(*numbers):
    fractions = [Fraction(n).limit_denominator() for n in numbers]
    multiple  = reduce(lcm, [f.denominator for f in fractions])
    ints      = [int(f * multiple) for f in fractions]
    divisor   = reduce(gcd, ints)
    return [int(n / divisor) for n in ints]

这会将每个数字转换为有理数fraction,然后将它们乘以分母的最小公倍数(LCM)。这有效地放大了它们,所以它们都是整数。然后用它们的集体GCD将它们分开,尽可能地缩小它们

例如:

>>> common_integer('0.2', '0.3', '0.6')
[2, 3, 6]
>>> common_integer('1424.56', '2136.84', '4985.96')
[2, 3, 7]
>>> common_integer('2/7', '18/42', '1/3')
[6, 9, 7]

(使用limit_denominator()允许传入浮点,即使是不精确的浮点。不完全建议这样做,但您可以省略引号并传递0.2来代替'0.2'1/3来代替'1/3'。)

在整数中,您正在寻找最大公约数。有很多算法可以找到它。然后,您需要将该逻辑转换为浮点数,请记住,浮点数算术意味着接近零的值可能应被视为零:

#!/usr/local/bin/python3

from functools import reduce

def iszero(a):
    return abs(a)<1e-9

def gcd(a,b):
    if iszero(b):
        return a
    return gcd(b,a%b)

def gcdarr(arr):
    return reduce(gcd,arr)

def correctratios(arr):
    arrgcd = gcdarr(arr)
    return [round(a/arrgcd) for a in arr]

l = [.2,.3,.6]
n2 = [1424.56, 2136.84, 4985.96]

print(correctratios(l))
print(correctratios(n2))

打印出:

[2, 3, 6]
[2, 3, 7]

Python 3.5引入了math.isclose,您可以使用它来代替iszero。它还将gcd从fractions移至math。内置gcd的问题在于它没有考虑到浮点接近于零的情况,所以一切都会崩溃

相关问题 更多 >