n次方
1、问题描述
计算 an
2、算法分析
先将 n 变一变,寻找新的计算路径。预处理就是变治法的根本。
如果单纯循环执行 n 次相乘,那么时间复杂度为 O(n)。可以利用二进制幂大大改进效率。
主要思路是:将十进制的 n 转换成二进制的数组序列 b[]。二进制幂求解有两种方法:从左至右二进制幂和从右至左二进制幂。
从左至右二进制幂
变换: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])
从右至左二进制幂
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次方的更多相关文章
- [LeetCode] Super Pow 超级次方
Your task is to calculate ab mod 1337 where a is a positive integer and b is an extremely large posi ...
- [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 ...
- [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 ...
- [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 ...
- [LeetCode] Pow(x, n) 求x的n次方
Implement pow(x, n). 这道题让我们求x的n次方,如果我们只是简单的用个for循环让x乘以自己n次的话,未免也把LeetCode上的想的太简单了,一句话形容图样图森破啊.OJ因超时无 ...
- 剑指Offer面试题:10.数值的整数次方
一.题目:数值的整数次方 题目:实现函数double Power(doublebase, int exponent),求base的exponent次方.不得使用库函数,同时不需要考虑大数问题. 在.N ...
- GDUFE-OJ 1203x的y次方的最后三位数 快速幂
嘿嘿今天学了快速幂也~~ Problem Description: 求x的y次方的最后三位数 . Input: 一个两位数x和一个两位数y. Output: 输出x的y次方的后三位数. Sample ...
- 《剑指offer》面试题11: 数值的整数次方
面试题11: 数值的整数次方 剑指offer面试题11,题目如下 实现函数double power(double base,int exponent),求base的exponent次方, 不得使用库 ...
- 打出10的n次方,上标,下标等处理方法(mac)
我使用mac系统遇到的需求,需要在项目中显示10的6次方 用来做单位,找了很多方案,word等文本编辑工具很好实现(word是使用ctrl + shift + =)(mac 版的word是 Comm ...
- 计算2的N次方&&计算e
2的N次方 注意:这里在处理的时候并没有用循环来处理,而是用移位的做法. n<<4 就是 n*2^4 ,所以在本例中只需要写 1<<time (time是要求的 ...
随机推荐
- Spring常见注解
@Autowired @Resource @Component:类加上@Component注解,即表明此类是bean @Aspect 注解表示这是一个切面 @Around(value = " ...
- Windows GDI 窗口与 Direct3D 屏幕截图
前言 Windows 上,屏幕截图一般是调用 win32 api 完成的,如果 C# 想实现截图功能,就需要封装相关 api.在 Windows 上,主要图形接口有 GDI 和 DirectX.GDI ...
- Maven项目中的packaging标签
<packaging>XXX</packaging> 项目的打包类型xxx:pom.jar.war.(packing默认是jar类型). pom是最简单的打包类型,pom 项目 ...
- Hibernate入门之注解@Column详解
前言 上一节我们讲解了Hibernate的主键生成策略,本节我们继续来讲讲Hibernate中针对列的映射即@Column注解,文中若有错误之处,还望指正. @Column注解详解 我们看到如上针对列 ...
- 正式学习MVC 01
1.新建项目 点击创建新项目,选择ASP.NET web应用程序,对项目进行命名后点击创建. 截图如下: 取消勾选HTTPS配置 可选择空 + mvc 或直接选定MVC 2.目录结构分析 1) App ...
- 【开发技巧】再见,BLE的那些坑!
蓝牙,平常你用的多吗?上班路上戴着蓝牙耳机听音乐.看视频打开蓝牙分享个人热点给小伙伴们解锁共享单车时,打开蓝牙就能迅速解锁...... BLE-蓝牙低能耗技术,方便了我们的生活,但是开发者在开发过程中 ...
- 自己查与写的批量比较bash
前言:互测的时候一个一个输入感觉太麻烦,于是尝试写自己的对拍,又想到os刚学了bash命令行处理,于是想把两者结合一下减轻自己的工作量 分两步: 将所有人的工程导出成jar文件 放到linux下用ba ...
- Error : Failed to get convolution algorithm. This is probably because cuDNN failed to initialize
记录一下: 报错:# Error : Failed to get convolution algorithm. This is probably because cuDNN failed to ini ...
- Android模拟器不能上网的解决方法
我原来一直不用Android的模拟器,因为这东西的多年前的印象真的是很糟糕——启动半个小时,不支持OpenGL.即使后来有了x86镜像,在HAXM的支持下快的飞起,也不想用,因为NDK还要编译x86的 ...
- 神奇的 SQL 之扑朔迷离 → ON 和 WHERE,好多细节!
开心一刻 楼主:心都让你吓出来了! 狮王:淡定,打个小喷嚏而已 前情回顾 神奇的 SQL 之 联表细节 → MySQL JOIN 的执行过程(一)中,我们讲到了 3 种联表算法:SNL.BNL 和 I ...