数值的整数次方(C++ 和 Python 实现)
(说明:本博客中的题目、题目详细说明及参考代码均摘自 “何海涛《剑指Offer:名企面试官精讲典型编程题》2012年”)
题目
实现函数 double Power(double base, int exponent),求 base 的 exponent 次方。不得使用库函数,同时不需要考虑大数问题。
算法设计思想
无论是简单直接方法,还是高效的方法,都需要首先全面考虑 base 和 exponent 的可能的输入:正数、负数和 0。实现的基本思想是把数值的整数次方,转化为数值的非负整数次方,然后根据指数的符号,再做相应处理,具体如下:
假设求解 a 的 n 次方,在指数 n 为正整数的前提下,简单直接方法就是将结果依次,就将结果乘以 base 几次,此时算法的时间复杂度为 O(n);
高效算法利用下面的公式,此时算法的时间复杂度为 O(logn)。

若指数 n 为负整数,则可先求 a 的 -n 次方,最后将计算结果取倒数,即可。此时需要注意,分母不能为 0,即 a 的 -n 次方的结果不能为 0,也就是说,当 n 为负整数时,a 不能为 0。
若指数 n 为 0 时,只要 a 不等于 0,则计算结果为 1;若 a 为 0 时,则为 0 的 0 次方,没有意义。
注:
易错点,将浮点数(float 或 double)使用 == 符号与 0 直接比较,以判断此数值是否为 0。因为浮点数在计算机中的表示是有误差的,所以不是直接使用 == 符号判断某浮点数是否为 0。在实现时,往往需要判断浮点数是否在数值 0.0 附近的小范围之内,若是,则判定此数值为 0。本博文中,取 10 的 -7 次方(1e-7)作为误差范围。
C++ 实现
/*
* Author: klchang
* Date: 2018.1.14
* Description: Compute the integer power of a numeric value.
*/ #include <iostream>
#include <exception> // Exception class for invalid input: base = 0 when exponent is negative.
class InvalidInputException: public std::exception {
// virtual function does not throw any exception
virtual const char* what() const throw()
{
return "Invalid input exception happened.";
} } invalid_input; // power function with non-negative exponent in the common method
// parameters:
// base - <0, =0, >0; exponent - =0 or >0
double power_common(double base, unsigned int exponent)
{
double result = ; for (int i = ; i < exponent; ++ i) {
result *= base;
} return result;
} // power function with non-negative exponent in the common method
// parameters:
// base - <0, =0, >0; exponent - =0 or >0.
double power_fast(double base, unsigned int exponent)
{
double result = ; if ( == exponent)
return ;
else if ( == exponent)
return base;
else {
// odd number
result = power_fast(base, exponent >> );
if (exponent & ) {
// odd number
return result * result * base;
} else {
// even number
return result * result;
}
}
} // Check if a double value is zero
bool is_zero(double value)
{
double zero_limit = 1e-; return (value >= - * zero_limit) && (value <= zero_limit);
} // generic interface for power function with integer exponent including positives, zero and negatives
// parameters:
// method: 1 -- fast method; others -- common method
double Power(double base, int exponent, int method=)
{
int sign = ; // default: positive exponent
double result; if (exponent <= ) {
if (is_zero(base)) { // fallibility: use 0 == base(double type)
// illegal input: 0^0 no meaning; 0^negative_integer error
throw invalid_input;
}
sign = -;
exponent = - exponent;
} if ( == method) // fast method
result = power_fast(base, (unsigned int)exponent);
else // common method
result = power_common(base, (unsigned int)exponent); if (sign < ) {
result = 1.0 / result;
} return result;
} void unitest()
{
try {
std::cout << "---------------- Power function in Fast Method Test ----------------" << std::endl
<< "The result of -2^-3 is " << Power(-, -, ) << std::endl
<< "The result of -2^3 is " << Power(-, , ) << std::endl
<< "The result of 2^-3 is " << Power(, -, ) << std::endl
<< "The result of 2^3 is " << Power(, , ) << std::endl;
std::cout << "---------------- Power function in Common Method Test ----------------" << std::endl
<< "The result of -2^-3 is " << Power(-, -) << std::endl
<< "The result of -2^3 is " << Power(-, ) << std::endl
<< "The result of 2^-3 is " << Power(, -) << std::endl
<< "The result of 2^3 is " << Power(, ) << std::endl;
}
catch(std::exception& e) {
std::cerr << e.what() << '\n';
}
} int main()
{
unitest(); return ;
}
Python 实现
#!/usr/bin/python
# -*- coding: utf8 -*-
"""
# Author: klchang
# Date: 2018.1.14
# Description: Compute the integer power of a numeric value.
""" # Invalid input exception class
class InvalidInput(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value) # power function with non-negative exponent in the common method
def power_common(base, exponent):
result = 1 for i in range(exponent):
result *= base; return result # power function with non-negative exponent in the fast method
def power_fast(base, exponent):
if 0 == exponent:
return 1
elif 1 == exponent:
return base
else:
result = power_fast(base, exponent >> 1)
if exponent & 1:
# odd integer
return result * result * base
else:
# even integer
return result * result # Check if value (int/float) is zero
# parameters:
# value - int type or float type
def is_zero(value):
# Check the type that value belongs to
if isinstance(value, float):
# float type
zero_limit = 1e-7
return (value >= -zero_limit) and (value <= zero_limit)
else:
# int type
return value == 0 # Generic interface for power function with integer exponent including positives, zero and negatives
# parameters:
# method: 1 -- fast method; others -- common method
def power(base, exponent, method=0):
# sign flag: positive(default)
is_positive_exponent = True
if exponent <= 0:
if is_zero(base):
raise InvalidInput(base)
exponent = - exponent
is_positive_exponent = False
# computation result
result = 0
if 1 == method:
result = power_fast(base, exponent)
else:
result = power_common(base, exponent)
# check the sign of the exponent
if not is_positive_exponent:
result = 1.0 / result return result def unitest():
try:
print("---------------- Power function in Fast Method Test ----------------")
print("The result of -2^-3 is %f." % power(-2, -3, 1))
print("The result of -2^3 is %f." % power(-2, 3, 1))
print("The result of 2^-3 is %f." % power(2, -3, 1))
print("The result of 2^3 is %f."% power(2, 3, 1))
print("---------------- Power function in Common Method Test ----------------")
print("The result of -2^-3 is %f." % power(-2, -3))
print("The result of -2^3 is %f." % power(-2, 3))
print("The result of 2^-3 is " % power(0, -3))
print("The result of 2^3 is " % power(2, 3))
except Exception as e:
print("Invalid input exception happened: input %s with negative exponent" % e) if __name__ == '__main__':
unitest()
参考代码
1. targetver.h
#pragma once // The following macros define the minimum required platform. The minimum required platform
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
// your application. The macros work by enabling all features available on platform versions up to and
// including the version specified. // Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
#endif
2. stdafx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
// #pragma once #include "targetver.h" #include <stdio.h>
#include <tchar.h> // TODO: reference additional headers your program requires here
3. stdafx.cpp
// stdafx.cpp : source file that includes just the standard includes
// Power.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information #include "stdafx.h" // TODO: reference any additional headers you need in STDAFX.H
// and not in this file
4. Power.cpp
// Power.cpp : Defines the entry point for the console application.
// // 《剑指Offer——名企面试官精讲典型编程题》代码
// 著作权所有者:何海涛 #include "stdafx.h"
#include <math.h> bool g_InvalidInput = false;
bool equal(double num1, double num2);
double PowerWithUnsignedExponent(double base, unsigned int exponent); double Power(double base, int exponent)
{
g_InvalidInput = false; if(equal(base, 0.0) && exponent < )
{
g_InvalidInput = true;
return 0.0;
} unsigned int absExponent = (unsigned int)(exponent);
if(exponent < )
absExponent = (unsigned int)(-exponent); double result = PowerWithUnsignedExponent(base, absExponent);
if(exponent < )
result = 1.0 / result; return result;
} /*
double PowerWithUnsignedExponent(double base, unsigned int exponent)
{
double result = 1.0;
/
for(int i = 1; i <= exponent; ++i)
result *= base; return result;
}
*/
double PowerWithUnsignedExponent(double base, unsigned int exponent)
{
if(exponent == )
return ;
if(exponent == )
return base; double result = PowerWithUnsignedExponent(base, exponent >> );
result *= result;
if((exponent & 0x1) == )
result *= base; return result;
} bool equal(double num1, double num2)
{
if((num1 - num2 > -0.0000001)
&& (num1 - num2 < 0.0000001))
return true;
else
return false;
} // ====================测试代码====================
void Test(double base, int exponent, double expectedResult, bool expectedFlag)
{
double result = Power(base, exponent);
if(abs(result - expectedResult) < 0.00000001
&& g_InvalidInput == expectedFlag)
printf("Test passed.\n");
else
printf("Test failed.\n");
} int _tmain(int argc, _TCHAR* argv[])
{
// 底数、指数都为正数
printf("Test1 begins.\n");
Test(, , , false); // 底数为负数、指数为正数
printf("Test2 begins.\n");
Test(-, , -, false); // 指数为负数
printf("Test3 begins.\n");
Test(, -, 0.125, false); // 指数为0
printf("Test4 begins.\n");
Test(, , , false); // 底数、指数都为0
printf("Test5 begins.\n");
Test(, , , false); // 底数为0、指数为正数
printf("Test6 begins.\n");
Test(, , , false); // 底数为0、指数为负数
printf("Test7 begins.\n");
Test(, -, , true); return ;
}
5. 参考代码下载
项目 11_Power 下载: 百度网盘
何海涛《剑指Offer:名企面试官精讲典型编程题》 所有参考代码下载:百度网盘
参考资料
[1] 何海涛. 剑指 Offer:名企面试官精讲典型编程题 [M]. 北京:电子工业出版社,2012. 84-93.
数值的整数次方(C++ 和 Python 实现)的更多相关文章
- 【剑指Offer】数值的整数次方 解题报告(Python)
[剑指Offer]数值的整数次方 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://www.nowcoder.com/ta/coding-interviews ...
- 《剑指offer》 数值的整数次方
本题来自<剑指offer> 数值的整数次方 题目: 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. 思路: 代码从三个方面处 ...
- 剑指Offer面试题:10.数值的整数次方
一.题目:数值的整数次方 题目:实现函数double Power(doublebase, int exponent),求base的exponent次方.不得使用库函数,同时不需要考虑大数问题. 在.N ...
- 《剑指offer》面试题11: 数值的整数次方
面试题11: 数值的整数次方 剑指offer面试题11,题目如下 实现函数double power(double base,int exponent),求base的exponent次方, 不得使用库 ...
- 九度OJ 1514 数值的整数次方【算法】
题目地址:http://ac.jobdu.com/problem.php?pid=1514 题目描述: 给定一个double类型的浮点数base和int类型的整数exponent.求base的expo ...
- 1514:数值的整数次方 @jobdu
题目1514:数值的整数次方 时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:377 解决:103 题目描述: 给定一个double类型的浮点数base和int类型的整数exponent. ...
- 用log(N)的解法实现数值的整数次方
// // main.m // c++test // // Created by andyyang on 6/3/13. // Copyright (c) 2013 andyyang. All rig ...
- 剑指offer编程题Java实现——面试题11数值的整数次方
题目: 实现函数double power(double base,int exponent),求base的exponent次方.不得使用库函数,同时不需要考虑大数问题. 解题思路:最一般的方法实现数值 ...
- 【Java】 剑指offer(15) 数值的整数次方
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 实现函数double Power(double base, int ...
随机推荐
- OS X获取process.env.NODE_ENV出错
原来项目是其它小组在维护,现在我们需要维护部分功能,把项目带到OS X上运行发现 webpack.config.js获取process.env.NODE_ENV变量出错 解决: 根据电脑操作系统平台类 ...
- SpringBoot进阶用法-随笔
SpringBoot进阶用法 实现setApplicationContext //实现ApplicationContextAware接口,重写setApplicationContext方法 publi ...
- c# 抽象类 抽象方法
抽象类与非抽象类的主要区别: ·抽象类不能直接被实例化 ·抽象类中可以包含抽象成员,但非抽象类中不可以 ·抽象类不能被密封 声明抽象方法时需注意:·抽象方法必须声明在抽象类中 ·声明抽象方法时,不能使 ...
- Mac 10.12安装数据库管理工具MySQL Workbench
说明:跨平台的MySQL管理工具.别纠结是不是反人类的了,这款用熟了也很溜. 下载: (链接: https://pan.baidu.com/s/1b3VtmA 密码: 6hka)
- Mac下使用PF进行端口转发和防火墙配置(类似Linux的iptables)
在Mac没有iptables这些,替代的软件为PF,命令为pfctl.在早些版本用ipfw(<=10.10),后面改为PF.还有一些可以使用OpenBsd,不过这个不太好用. 网上关于pfctl ...
- xampp使用技巧及问题汇总
1)在win7上同时装有IIS 和 xampp1.8.2 ,会出现Apache启动时,提示80端口被占用的情况(一般是iis安装之后出现的常见情况). 情况1: xampp 在启动时会检测Apach ...
- 【Maven学习】maven-enforcer-plugin的使用
我们会经常碰到这样的问题,在pom中引入了一个jar,里面默认依赖了其他的jar包.jar包一多的时候,我们很难确认哪些jar是我们需要的,哪些jar是冲突的.此时会出现很多莫名其妙的问题,什么类找不 ...
- WPF 使用依赖属性自定义控件
使用依赖属性自定义控件,依赖属性必须定义在自定义控件中,不能定义在其他文件中 一.先实现一个类继承你要复写的类 using System; using System.Collections.Gener ...
- Executors多线程
介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...
- angular环境搭建时的坑
安装angular环境踩过一些坑,最终还是把工程跑起来了,这里描述一下我的步骤,不排除有些步骤是多余的,希望能对遇到同样问题的小伙伴有帮助. 下载最新版node.js. 安装node,安装过程一路点下 ...