Algorithm 如何用最简单的方法找到某个幂的单位数字

Algorithm 如何用最简单的方法找到某个幂的单位数字,algorithm,math,language-agnostic,pseudocode,Algorithm,Math,Language Agnostic,Pseudocode,如何找出某个数字的单位数字(例如3 power 2011)。我应该使用什么逻辑来找到这个问题的答案?对于base 3: 3^1 = 3 3^2 = 9 3^3 = 27 3^4 = 81 3^5 = 243 3^6 = 729 3^7 = 2187 ... 也就是说,单位数字只有4种可能,然后在同一个周期内重复 借助于,我们可以证明这适用于任何整数n,这意味着它们的单位数字在最多4个连续指数之后将重复。仅查看任意乘积的单位数字相当于取乘法模10的剩余部分,例如: 2^7 % 10 = 128

如何找出某个数字的单位数字(例如
3 power 2011
)。我应该使用什么逻辑来找到这个问题的答案?

对于base 3:

3^1 = 3
3^2 = 9
3^3 = 27
3^4 = 81
3^5 = 243
3^6 = 729
3^7 = 2187
...
也就是说,单位数字只有4种可能,然后在同一个周期内重复

借助于,我们可以证明这适用于任何整数n,这意味着它们的单位数字在最多4个连续指数之后将重复。仅查看任意乘积的单位数字相当于取乘法模10的剩余部分,例如:

2^7 % 10 = 128 % 10 = 8 
还可以显示(并且非常直观)对于任意基数,任何幂的单位数字将仅取决于基数本身的单位数字-即2013^2013与3^2013具有相同的单位数字

我们可以利用这两个事实提出一个极快的算法(感谢您的允许,我可以提供一个更快的版本)

想法是这样的:我们知道,对于任何数字0-9,最多会有4种不同的结果,我们也可以将它们存储在查找表中:

{ 0,0,0,0, 1,1,1,1, 6,2,4,8, 1,3,9,7, 6,4,6,4, 
  5,5,5,5, 6,6,6,6, 1,7,9,3, 6,8,4,2, 1,9,1,9 }
这是0-9的可能结果,按顺序分为四组。现在的想法是将n^a求幂到

  • 首先取基本模式10=>:=
    i
  • 转到表中的索引
    4*i
    (它是该特定数字的起始偏移量)
  • 取指数mod 4=>:=
    (如欧拉定理所述,我们只有四种可能的结果!)
  • off
    添加到
    4*i
    以获得结果
现在,为了尽可能提高效率,对基本算术运算进行了一些调整:

  • 乘以4相当于将2向左移动('=10,因此我们可以说x=x_0+10*x_1+100*x_2+…(以10为基数表示)

    使用模块化表示很容易看出这一点

    x ^ y mod 10
    = (x_0 + 10*x_1 + 100*x_2 + ...) ^ y mod 10
    = x_0^y + a_1 * (10*x_1)^y-1 + a_2 * (100*x_2)^y-2 + ... + a_n * (10^n) mod 10
    = x_0^y mod 10  
    

    式中,a_i是包括x_0的幂的系数,但最终不相关,因为整个乘积a_i*(10*x_i)^y-i可以被10整除。

    我肯定有一个合适的数学方法来解决这个问题,但我建议,因为你只关心最后一个数字,而且从理论上讲,每一个重复乘以自身的数字最终应该生成一个重复模式(当只看最后一个数字时),您可以简单地执行乘法,直到检测到第一次重复,然后将指数映射到您构建的模式中的适当位置

    请注意,因为您只关心最后一位数字,所以在开始构建模式映射之前,您可以通过将输入数字截断为一位数字来进一步简化操作。这将允许您确定最后一位数字,即使是任意大的输入,否则会导致第一次或第二次乘法溢出

    下面是JavaScript中的一个基本示例:

    函数最后一位(基数、指数){
    if(指数<0){
    警报(“愚蠢的用户,不支持负值”);
    返回0;
    }
    如果(指数=0){
    返回1;
    }
    var baseString=基本值+“”;
    var lastBaseDigit=baseString.substring(baseString.length-1);
    var lastDigit=lastBaseDigit;
    var模式=[];
    做{
    模式推送(最后一位);
    var nextProduct=(lastDigit*lastBaseDigit)+'';
    lastDigit=nextProduct.substring(nextProduct.length-1);
    }while(lastDigit!=lastBaseDigit);
    返回模式[(指数-1)%pattern.length];
    };
    函数doMath(){
    var base=parseInt(document.getElementById(“base”).value,10);
    var exp=parseInt(document.getElementById(“exp”).value,10);
    log(lastDigit(base,exp));
    };
    console.log(最后一位数字(3003,5));
    Base:
    指数:

    下面是一个功率表,该功率的单位数字为3。
    01
    13
    29
    37
    4.1
    5.3
    6.9
    7

    使用此表,您可以看到单位数字可以是1、3、9、7,并且序列按此顺序重复以获得更高的3次方。使用此逻辑,您可以发现(3次方2011)的单位数字是7。您可以在一般情况下使用相同的算法。

    您应该查看。您想要的是计算n^e(mod m)的相同方法m=10。这与计算n^e除以10的余数是一样的

    您可能对计算它的方法感兴趣,因为它是最省时且最容易实现的方法。以下是来自Wikipedia的伪代码:

    function modular_pow(base, exponent, modulus)
        result := 1
        while exponent > 0
            if (exponent & 1) equals 1:
               result = (result * base) mod modulus
            exponent := exponent >> 1
            base = (base * base) mod modulus
        return result
    
    在那之后,用模数=10来表示你想要的基数和指数,这就是你的答案

    编辑:对于一个更简单的方法,效率更低的CPU,但更内存,请查看Wikipedia上的文章部分。逻辑非常简单:

    function modular_pow(base, exponent, modulus)
        c := 1
        for e_prime = 1 to exponent 
            c := (c * base) mod modulus
        return c
    

    我们可以从检查每个结果的最后一位开始,将基数10提高到连续幂:

    d      d^2    d^3    d^4    d^5    d^6    d^7    d^8    d^9 (mod 10)
    ---    ---    ---    ---    ---    ---    ---    ---    ---
    0      0      0      0      0      0      0      0      0
    1      1      1      1      1      1      1      1      1
    2      4      8      6      2      4      8      6      2
    3      9      7      1      3      9      7      1      3
    4      6      4      6      4      6      4      6      4
    5      5      5      5      5      5      5      5      5
    6      6      6      6      6      6      6      6      6
    7      9      3      1      7      9      3      1      7
    8      4      2      6      8      4      2      6      8
    9      1      9      1      9      1      9      1      9
    
    我们可以看到,在所有情况下,最后一个数字循环通过不超过四个不同的值。利用这一事实,并假设
    n
    是非负整数,
    p
    是正整数,我们可以相当直接地计算结果(例如,在Javascript中):

    …或者更简单地说:

    function lastDigit(n, p) {
        return Math.pow(n % 10, (p-1) % 4 + 1) % 10;
    }
    
    lastDigit(3, 2011)
    /* 7 */
    

    第二个函数与第一个函数等效。请注意,尽管它使用了幂运算,但对于大于九到四次方(6561)的数字,它永远不会起作用。

    解决这类问题的关键在于

    这个定理允许我们说a^phi(m)mod m=1 mod m,当且仅当a和m是互质的。也就是说,a和m不是等分的。如果是这样的话,(你的例子就是这样),我们可以在纸上解决这个问题,而无需任何编程

    让我们求解3^2011的单位数字,如您的示例中所示。这相当于3^2011 mod 10

    第一
    function modular_pow(base, exponent, modulus)
        result := 1
        while exponent > 0
            if (exponent & 1) equals 1:
               result = (result * base) mod modulus
            exponent := exponent >> 1
            base = (base * base) mod modulus
        return result
    
    function modular_pow(base, exponent, modulus)
        c := 1
        for e_prime = 1 to exponent 
            c := (c * base) mod modulus
        return c
    
    d      d^2    d^3    d^4    d^5    d^6    d^7    d^8    d^9 (mod 10)
    ---    ---    ---    ---    ---    ---    ---    ---    ---
    0      0      0      0      0      0      0      0      0
    1      1      1      1      1      1      1      1      1
    2      4      8      6      2      4      8      6      2
    3      9      7      1      3      9      7      1      3
    4      6      4      6      4      6      4      6      4
    5      5      5      5      5      5      5      5      5
    6      6      6      6      6      6      6      6      6
    7      9      3      1      7      9      3      1      7
    8      4      2      6      8      4      2      6      8
    9      1      9      1      9      1      9      1      9
    
    function lastDigit(n, p) {
        var d = n % 10;
        return [d, (d*d)%10, (d*d*d)%10, (d*d*d*d)%10][(p-1) % 4];
    }
    
    function lastDigit(n, p) {
        return Math.pow(n % 10, (p-1) % 4 + 1) % 10;
    }
    
    lastDigit(3, 2011)
    /* 7 */
    
    3^2011 mod 10 = 3^(4*502 + 3) mod 10 = 3^(4*502) mod 10 + 3^3 mod 10 = 1^502 * 3^3 mod 10 = 27 mod 10 = 7
    
    // Find the smallest power of b ending in 1.
    i=1
    while ((b^i % B) != 1) {
        i++
    }
    // b^i has the last digit 1
    
    a=n % i
    // For some value of j, b^n == (b^i)^j * b^a, which is congruent to b^a
    return b^a % B
    
    divide the power xyz by 4,if remainder is 1 ans is c^1=c.
     if xyz%4=2 ans is unit digit of  c^2.
     else if xyz%4=3 ans is unit digit of  c^3.
    
     if xyz%4=0 
     then we need to check whether c is 5,then ans is 5
      if c is even ans is 6
     if c is odd (other than 5 ) ans is 1.
    
    def last_digit(n1, n2)
      if n2==0 then return 1 end
      last = n1%10
      mod = (n2%4).zero? ? 4 : (n2%4)
      last_digit = (last**mod)%10
    end