一、题目描述
这是一道经典的面试题,需要我们在不使用任何内置函数的前提下,手动实现求指定整数的算术平方根。
1.题目内容
给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5
原题链接:https://leetcode.cn/problems/sqrtx/
2.样例
二、解决方案
1.基本代码(成功提交)
可以明确的是,此处题目要求计算结果直接将小数部分舍去,只保留整数部分,如样例中8的平方根最后返回2。我采用遍历穷举的方法求解此题,大概思路如下:
- 初始化局部变量res,存储开根号计算结果;
- 设置迭代变量i=1开始,计算其平方与指定数num进行比较:如果是偶数则可以在某个i值时正好开方,此时res=i;而对于奇数则判断某个i时其平方值刚好大于num,此时说明sqrt(num)一定小于i,并且大于i-1,因为只用返回其算术平方根的整数部分,所以可以直令res=i-1;
- 此处比较特殊的两个值是0和1,对于0直接返回0本身;而为了使num=1时可以正常计算,我咋外层循环时令终止条件为i<int(num+1);
def mySqrt(num):
res=0
if num==0:
return 0
i=1
while i<int(num+1):
# print(i)
if i*i == num: # 如果正好可以开方
res = i
break
elif i*i > num: # 如果刚好大于这个数
res=i-1
break
i+=1
return int(res)
2.略微拓展
在这里我稍微对上面的解答做了细微的扩展,具体改变如下:
- 循环输入非负数计算其算术平方根;
- 我通过设置一个误差精度epsilon,逼近运算结果与其真实值;
- 这里需要注意的就是,在碰到num为奇数情况时,sqrt(num)一定满足范围:i-1<sqrt(num)<i,此时设置一个很小的步长stride去尝试计算;
- 当计算结果满足精度要求时停止迭代,返回计算结果即可;
# -*- coding: utf-8 -*-
# create time:2022/10/9
'''
手动实现开放运算:
1.输入一个整数
2.计算开根号
3.输出开根结果
'''
import math
def sqrt_operator(num,epsilon):
res=0
if num==0:
res=0
i=1
while i<int(num+1):
# print(i)
if math.pow(temp, 2) == num: # 如果正好可以开方
res = i
break
elif math.pow(temp, 2) > num: # 如果刚好大于这个数
stride = 0.0001 # 设置步长
temp=i - 1
while temp <i:
if math.fabs(math.pow(temp, 2) -num)<epsilon:
res = temp
break
temp+=stride
if temp<i:
break
i+=1
return res
def main():
num = float(input("输入一个非负数:"))
# print(mySqrt(num))
# num=7
epsilon=0.001 # 精度误差
while num >= 0: # 循环输入,直到输入一个负整数
sqrt_num = sqrt_operator(num,epsilon)
print('-' * 10)
print("根号{}是{}".format(str(num), str(sqrt_num)), )
num = float(input("输入一个非负数:"))
if __name__ == '__main__':
main()
运行结果如下图所示: