1、问题描述

计算 an

2、算法分析

先将 n 变一变,寻找新的计算路径。预处理就是变治法的根本。

如果单纯循环执行 n 次相乘,那么时间复杂度为 O(n)。可以利用二进制幂大大改进效率。

主要思路是:将十进制的 n 转换成二进制的数组序列 b[]。二进制幂求解有两种方法:从左至右二进制幂和从右至左二进制幂。

  1. 从左至右二进制幂

    变换:an = a(b[n]2m + ... + b[0]20)

    先求 n 的二进制串,如:n = 5 => 1 0 1,那么 b[2] = 1, b[1] = 0, b[0] = 1

    二进制求 n 的伪代码:

    Horner(b[0...n], x)
    k = b[n]
    for i = n-1 downto 0 do
      p = x*k + b[i]
    return p

    那么 n 用作 a 的指数时意义是什么样的呢:

    ap = a1

    for i = n - 1 downto 0 do

      ap = a(2p+b[i])

  2. 从右至左二进制幂

    n 变换方法与上面相同,然后从 b[0] -> b[n] 方向逐步求解。

    时间复杂度:O(logn)

3、代码实现

#include <stdio.h>
#include <stdlib.h> /**
* @brief 返回 x 的二进制串(数组)
*/
int GetBinArray(int x, int arr[], int length)
{
int idx = 0; while(x > 0) { // 获取末位的二进制
arr[idx++] = (x & 1) ? 1 : 0;
if (idx == length)
break; // 右移两位
x = x >> 1;
} return idx;
} /**
* @brief a^n = a^(b[n]2^n + ... + b[0]2^0)= a^(b[n]2^n)* ... * a^b[0]。 b 数组元素不是 1 就是 0
*/
int Pow_Bin_RightToLeft(int number, int power)
{
if (power == 0)
return 1; int length = sizeof(int) * 8; // 32
int *pint = (int *)malloc(length); // 获取幂的二进制数组
length = GetBinArray(power, pint, length); int item = number;
int ret = 1; for (int i = 0; i < length; i++) { // 二进制值为 1,计入结果
if (pint[i] == 1)
ret *= item;
item *= item;
}
free(pint); return ret;
} /**
* @brief a^n = a^(b[n]2^n + ... + b[0]2^0)=((b[n]*2 + b[n-1])*X + ....)2 + b[0]。 b 数组元素不是 1 就是 0
*/
int Pow_Bin_LeftToRight(int number, int power)
{
if (power == 0)
return 1; int length = sizeof(int)*8;
int *pint = (int *)malloc(length); length = GetBinArray(power, pint, length); int ret = number; for (int i = length - 1 - 1; i >= 0; i--) { ret *= ret; if(pint[i] == 1)
ret *= number;
} free(pint); return ret;
} int main()
{
int num = 8, power = 6;
int ret1 = Pow_Bin_RightToLeft(num, power);
int ret2 = Pow_Bin_LeftToRight(num, power); printf("Pow_Bin_RightToLeft: %d^%d == %d\n", num, power, ret1);
printf("Pow_Bin_LeftToRight: %d^%d == %d\n", num, power, ret2); return 0;
} Pow_Bin_RightToLeft: 8^6 == 262144
Pow_Bin_LeftToRight: 8^6 == 262144

4、内容来源

计算 n 次方--变治法

n次方的更多相关文章

  1. [LeetCode] Super Pow 超级次方

    Your task is to calculate ab mod 1337 where a is a positive integer and b is an extremely large posi ...

  2. [LeetCode] Power of Four 判断4的次方数

    Given an integer (signed 32 bits), write a function to check whether it is a power of 4. Example: Gi ...

  3. [LeetCode] Power of Three 判断3的次方数

    Given an integer, write a function to determine if it is a power of three. Follow up:Could you do it ...

  4. [LeetCode] Power of Two 判断2的次方数

    Given an integer, write a function to determine if it is a power of two. Hint: Could you solve it in ...

  5. [LeetCode] Pow(x, n) 求x的n次方

    Implement pow(x, n). 这道题让我们求x的n次方,如果我们只是简单的用个for循环让x乘以自己n次的话,未免也把LeetCode上的想的太简单了,一句话形容图样图森破啊.OJ因超时无 ...

  6. 剑指Offer面试题:10.数值的整数次方

    一.题目:数值的整数次方 题目:实现函数double Power(doublebase, int exponent),求base的exponent次方.不得使用库函数,同时不需要考虑大数问题. 在.N ...

  7. GDUFE-OJ 1203x的y次方的最后三位数 快速幂

    嘿嘿今天学了快速幂也~~ Problem Description: 求x的y次方的最后三位数 . Input: 一个两位数x和一个两位数y. Output: 输出x的y次方的后三位数. Sample ...

  8. 《剑指offer》面试题11: 数值的整数次方

    面试题11: 数值的整数次方 剑指offer面试题11,题目如下 实现函数double power(double base,int exponent),求base的exponent次方, 不得使用库 ...

  9. 打出10的n次方,上标,下标等处理方法(mac)

    我使用mac系统遇到的需求,需要在项目中显示10的6次方 用来做单位,找了很多方案,word等文本编辑工具很好实现(word是使用ctrl + shift + =)(mac  版的word是 Comm ...

  10. 计算2的N次方&&计算e

    2的N次方 注意:这里在处理的时候并没有用循环来处理,而是用移位的做法.    n<<4  就是 n*2^4    ,所以在本例中只需要写 1<<time  (time是要求的 ...

随机推荐

  1. 从头认识js-HTML中使用JavaScript

    <script>元素 在HTML页面中插入Javascript的主要办法就是使用<script>元素,HTML4.01为<script>定义了下列6个属性. 1.a ...

  2. Day06 - Fetch、filter、正则表达式实现快速古诗匹配

    Day06 - Fetch.filter.正则表达式实现快速古诗匹配 作者:©liyuechun 简介:JavaScript30 是 Wes Bos 推出的一个 30 天挑战.项目免费提供了 30 个 ...

  3. react-native 使用leanclound消息推送

    iOS消息推送的基本流程 1.注册:为应用程序申请消息推送服务.此时你的设备会向APNs服务器发送注册请求.2. APNs服务器接受请求,并将deviceToken返给你设备上的应用程序 3.客户端应 ...

  4. bp(net core)+easyui+efcore实现仓储管理系统——入库管理之三存储过程(三十九)

    abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ...

  5. Ubuntu16.04如何安装bazel?

    官方文档:https://docs.bazel.build/versions/master/install-ubuntu.html 我没有使用二进制的安装方法,以下是二进制的安装方法: Install ...

  6. vijos 1011 清帝之惑之顺治

    背景 顺治帝福临,是清朝入关后的第一位皇帝.他是皇太极的第九子,生于崇德三年(1638)崇德八年八月二ten+six日在沈阳即位,改元顺治,在位18年.卒于顺治十八年(1661),终24岁. 顺治即位 ...

  7. 关于使用map存放数据乱序”问题“

    今天做项目中遇到了一个比较低级的错误,如果没注意将会变的更麻烦... 其实吧,也不难,要求就是将list中的值转为map后,再顺序输出map中的值,list的顺序怎样,加入到map的顺序也应怎样,不能 ...

  8. Javascript中的Math.max()和Math.min()

    Math.max()是求最大值,Math.min()是求最小值 Math.max(value1,value2,value3....) 但是如果是数组或者对象呢? var numArr = [1,2,4 ...

  9. JavaScript(6)--- 原型链

    原型链 再上一篇有简单讲过原型:JavaScript(5)--- 面向对象 + 原型 讲原型链知识之前,先说几个重要的结论. 1.原型链就是 对象的__proto__所连接的链状结构 2.protot ...

  10. Spring源码阅读笔记05:自定义xml标签解析

    在上篇文章中,提到了在Spring中存在默认标签与自定义标签两种,并且详细分析了默认标签的解析,本文就来分析自定义标签的解析,像Spring中的AOP就是通过自定义标签来进行配置的,这里也是为后面学习 ...