如何以最简单的方式找到某个功率的单位数字

时间:2011-08-27 12:05:29

标签: algorithm math language-agnostic pseudocode

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

10 个答案:

答案 0 :(得分:21)

对于基数3:

3^1 = 3
3^2 = 9
3^3 = 27
3^4 = 81
3^5 = 243
3^6 = 729
3^7 = 2187
...

即单位数字只有4种可能性,然后它会在同一个循环中重复。

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

2^7 % 10 = 128 % 10 = 8 

也可以显示(并且非常直观)对于任意基数,任何功率的单位数将仅取决于基本身的单位数 - 即2013 ^ 2013具有与3相同的单位数^ 2013。

我们可以利用这两个事实来提出一个非常快速的算法(感谢help - 我可以提供更快的版本)。

我们知道,对于任何数字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到

  • 首先取基础mod 10 => := i
  • 转到我们表格中的索引4*i(它是该特定数字的起始偏移量)
  • 取指数mod 4 => := off(如欧拉定理所述,我们只有四种可能的结果!)
  • off添加到4*i以获得结果

现在为了尽可能提高效率,我们将对基本算术运算进行一些调整:

  • 乘以4相当于向左移动两个('<<<<<<<<<<<<<<<<"<<"<<"
  • 使用数字a % 4相当于说a&3(屏蔽1位和2位,形成余数%4)

C中的算法

static int table[] = {
    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
};

int /* assume n>=0, a>0 */ 
unit_digit(int n, int a)
{
    return table[((n%10)<<2)+(a&3)];
}

初始索赔的证据

从观察中我们注意到3 ^ x的单位数每四次重复一次。声称这适用于任何整数。但这实际上是如何证明的?事实证明,使用模运算很容易。如果我们只对单位数字感兴趣,我们可以以10为模数执行我们的计算。它相当于说4个指数之后的单位数周期或者说

a^4 congruent 1 mod 10

如果这样,那么例如

a^5 mod 10 = a^4 * a^1 mod 10 = a^4 mod 10 * a^1 mod 10 = a^1 mod 10

也就是说,^ 5产生与^ 1相同的单位数字,依此类推。

来自Euler's theorem我们知道

a^phi(10) mod 10 = 1 mod 10

其中phi(10)是1到10之间的数字,它们是10的共同素数(即它们的gcd等于1)。数字&lt; 10个共同素数到10个是1,3,7和9.所以phi(10)= 4,这证明真的是a^4 mod 10 = 1 mod 10

要证明的最后一个声明是,对于基数> = 10的指数,只需查看基数的单位数就足够了。假设我们的基数是x> = 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整除。

答案 1 :(得分:8)

我确信有一种合适的数学方法可以解决这个问题,但我建议你,因为你只关心最后一位数,因为理论上每一个数字本身重复乘以最终会产生一个重复模式(当只看到最后一个数字),您可以简单地执行乘法,直到您检测到第一次重复,然后将指数映射到您构建的模式中的适当位置。

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

以下是JavaScript中的基本示例:http://jsfiddle.net/dtyuA/2/

顺便说一句,3^2011中的最后一位数字是7。

答案 2 :(得分:8)

你应该看看Modular exponentiation。你想要的是用m = 10计算 n ^ e(mod m)的情况。这与计算除法的余数除以10相同。

你可能对Right-to-left binary method计算它感兴趣,因为它是最节省时间的,而最简单的并不太难实现。这是来自维基百科的伪代码:

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上文章的Memory-efficient部分。逻辑很简单:

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

答案 3 :(得分:3)

我们可以从检查每个结果的最后一位数开始,将基数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) {
    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 */

第二个功能相当于第一个功能。请注意,即使它使用取幂,它也不会使用大于9到4的幂数(6561)。

答案 4 :(得分:3)

解决此类问题的关键在于Euler's theorem

这个定理允许我们说a ^ phi(m)mod m = 1 mod m,当且仅当a和m是互质的时候。也就是说,a和m不均匀分配。如果是这种情况,(并且就你的例子而言),我们可以在纸上解决问题,而不需要任何编程。

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

第一步是检查是3和10是共同素数。它们不均匀分配,所以我们可以使用欧拉定理。

我们还需要计算totient或phi值为10的值。对于10,它是4.对于100 phi是40,1000是4000等。

使用欧拉定理,我们可以看到3 ^ 4 mod 10 = 1.然后我们可以重新编写原始示例:

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

因此,3 ^ 2011的最后一位数字是7。

如你所见,这不需要任何编程,我在一张草稿纸上解决了这个例子。

答案 5 :(得分:1)

你们让简单的事情变得复杂。

假设你想找出abc ^ xyz的单位数字。

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.

答案 6 :(得分:0)

贝娄是一张桌子,其功率和单位数为3。
0 1
1 3
2 9
3 7
4 1
5 3
6 9
7 7

使用此表,您可以看到单位数字可以是1,3,9,7,并且顺序将按此顺序重复,以获得更高的3次幂。使用此逻辑,您可以找到(3 power 2011)的单位数字)是7.您可以对一般情况使用相同的算法。

答案 7 :(得分:0)

这是一个适用于不是基数因子倍数的数字的技巧(对于基数10,它不能是2或5的倍数。)让我们使用基数3.你在尝试什么找到是3 ^ 2011 mod 10.找到3的幂,从3 ^ 1开始,直到找到一个最后一个数字1.对于3,你得到3 ^ 4 = 81。将原始功率写为(3 ^ 4)^ 502 * 3 ^ 3。使用模运算,(3 ^ 4)^ 502 * 3 ^ 3与(^具有相同的最后一位)1 ^ 502 * 3 ^ 3一致。因此3 ^ 2011和3 ^ 3具有相同的最后一位数,即7。

这里有一些伪代码来解释它。这将找到基数B中b ^ n的最后一位数。

// 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

如果b的幂没有以1结尾,则需要小心防止无限循环(在基数10中,2或5的倍数不起作用。)

答案 8 :(得分:0)

在这种情况下找出重复集,它是3,9,7,1并且它以相同的顺序重复......所以将2011除以4会给你提醒3.这是第3个元素在重复集中。这是找到任何给定号码的最简单方法。如果要求3 ^ 31,那么31/4的提醒是3,所以7是单位数字。对于3 ^ 9,9 / 4为1,因此单位为3. 3 ^ 100,单位为1。

答案 9 :(得分:0)

如果你有数字和指数分开,那很容易。

设n1为数字,n2为幂。 **代表权力。

假设n1> 0。

%表示模数除法。

伪代码看起来像这样

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

说明:

我们只需要考虑数字的最后一位数,因为这决定了数字的最后一位数。  它是数学属性,每个数字(0-9)幂的最后一位数的可能性计数最多为4.

1)现在如果指数为零,我们知道最后一位数字是1。

2)在数字(n1)

上获取%10的最后一位数字

3)指数上的%4(n2) - 如果输出为零,我们必须将其视为4,因为n2不能为零。如果%4不为零,我们必须考虑%4值。

4)现在我们最多有9 ** 4。这对于计算机来说很容易计算。    取这个数字的%10。你有最后一位数。

相关问题