简体   繁体   English

大数的最后一位数(幂)python

[英]Last digit of a large number(power) python

Found this on Codewars.在 Codewars 上找到了这个。 The function takes two arguments A and B and returns the last digit of A^B.该函数接受两个参数 A 和 B,并返回 A^B 的最后一位数字。 The code below passes the first two test cases, but won't pass the next ones.下面的代码通过了前两个测试用例,但不会通过接下来的测试用例。

def last_digit(n1, n2):
    number = n1**n2
    if number % 2 == 0:
        return number % 10
    elif number % 2 != 0:
        return number % 10

Test.it("Example tests")
Test.assert_equals(last_digit(4, 1), 4)
Test.assert_equals(last_digit(4, 2), 6)
Test.assert_equals(last_digit(9, 7), 9)
Test.assert_equals(last_digit(10, 10 ** 10), 0)

Don't compute n1**n2 .不要计算n1**n2 The problem comes when you attempt to compute:当您尝试计算时会出现问题:

10**(10**10)

That is a 1 followed by ten billion zeroes.那是一个 1 后跟 100 亿个零。

Use pow(n1, n2, 10) this makes the problem (more) tractable as it computes the exponentiation modulo 10 .使用pow(n1, n2, 10)这使得问题(更)易于处理,因为它计算取幂模10 Then as the number is already reduced modulo 10 the function can be rewritten as:然后由于数字已经减少了模 10,该函数可以重写为:

def last_digit(n1, n2):
    return pow(n1, n2, 10)

Problem is easy to solve once you realize that the last digits of powers form a cycle.一旦您意识到幂的最后一位数字形成一个循环,问题就很容易解决。 For example:例如:

2: 2, 4, 8, 6, 2, 4
3: 3, 9, 7, 1, 3, 9

With that in mind you can create the cycle first and then just index it with modulo of n2 :考虑到这一点,您可以先创建循环,然后使用n2模数对其进行索引:

def last_digit(n1, n2):
    if n2 == 0:
        return 1

    cycle = [n1 % 10]
    while True:
        nxt = (cycle[-1] * n1) % 10
        if nxt == cycle[0]:
            break
        cycle.append(nxt)
    return cycle[(n2 - 1) % len(cycle)]

This is also faster than using pow :这也比使用pow更快:

def last_digit_pow(n1, n2):
    return pow(n1, n2, 10)

if __name__ == '__main__':
    import timeit
    print(timeit.timeit("last_digit(10, 10 ** 10)", setup="from __main__ import last_digit"))
    print(timeit.timeit("last_digit_pow(10, 10 ** 10)", setup="from __main__ import last_digit_pow"))

Output (Windows 8 & Python 2.7):输出(Windows 8 和 Python 2.7):

0.832171277335
4.08073167307

Output (Windows 8 & Python 3.5):输出(Windows 8 和 Python 3.5):

0.6951034093766606
1.9045515428013722

Output with 10**100 (Windows 8 & Python 3.5):输出10**100 (Windows 8 和 Python 3.5):

0.8367381690724996
10.928452962508006

I know this post is old, but maybe someone will find this dictionary-based approach useful, too.我知道这篇文章很旧,但也许有人会发现这种基于字典的方法也很有用。

cycles = {
    0: [0,0,0,0],   
    1: [1,1,1,1],
    2: [2,4,8,6],
    3: [3,9,7,1],
    4: [4,6,4,6], 
    5: [5,5,5,5], 
    6: [6,6,6,6], 
    7: [7,9,3,1], 
    8: [8,4,2,6], 
    9: [9,1,9,1], 
}

def last_digit(n1, n2):
    if n2 == 0:
        return 1
    else:
        n1_last_digit = int(str(n1)[-1])
        cycle = cycles[n1_last_digit]
        return cycle[(n2 % 4) - 1]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM