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. 爬虫(二)requests 登陆某检索网站

    1 import requests import os from PIL import Image import pytesseract import re rootUrl = xxx # 构建登录页 ...

  2. python画一颗拳头大的💗

    用上turtle库后,各种画,今天画个拳头大的爱心@.@. 下面贴下代码: # -*- coding: utf-8 -*- # Nola import pygame import time impor ...

  3. Angular 从入坑到挖坑 - 表单控件概览

    一.Overview angular 入坑记录的笔记第三篇,介绍 angular 中表单控件的相关概念,了解如何在 angular 中创建一个表单,以及如何针对表单控件进行数据校验. 对应官方文档地址 ...

  4. Java设计模式之结构模式

    一.外观模式 分析:外观模式是为子系统的一组接口提供一个统一的界面,数据库JDBC连接应用就是外观模式的一个典型例子,特点:降低系统的复杂度,增加灵活性.结果:代码示例: public class D ...

  5. 简单说 通过CSS的滤镜 实现 火焰效果

    说明 上次我们了解了一些css滤镜的基础知识, 简单说 CSS滤镜 filter属性 这次我们就来用css的滤镜实现一个 火焰的效果. 解释 要实现上面的火焰效果,我们先来了解一些必要的东西. 上次我 ...

  6. javascript简单轮播图

    **轮播图实现原理: 通过多张图片平铺,用overflow:hidden只显示一张图片.其他的隐藏,无缝滚动用定时器改变元素的left值让图片呈现左右滚动的效果.** HTML布局和内容: 1.容器c ...

  7. 前端每日实战:4# 视频演示如何用纯 CSS 创作一个金属光泽 3D 按钮特效

    效果预览 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. https://codepen.io/zhang-ou/full/MGeRRO 可交互视频教程 此视频是可以 ...

  8. 群ping

    找出单位内所有电脑手机 通常情况下,ping只能ping一个IP地址.一个网络值班只有255台电脑,除非是大的网络断,把子网掩码改了,可以扩充更多电脑.如: 如果我们要一次性检查内网所有机器,则可以输 ...

  9. 看完这篇 HTTPS,和面试官扯皮就没问题了

    下面我们来一起学习一下 HTTPS ,首先问你一个问题,为什么有了 HTTP 之后,还需要有 HTTPS ?我突然有个想法,为什么我们面试的时候需要回答标准答案呢?为什么我们不说出我们自己的想法和见解 ...

  10. JVM03——四种垃圾回收算法,你都了解了哪几种

    在之前的文章中,已经为各位带来了JVM的内存结构与堆内存的相关介绍,今天将为为各位详解JVM垃圾回收与算法.关注我的公众号「Java面典」了解更多 Java 相关知识点. 如何确定垃圾 想要回收垃圾, ...