Java之判断大整数是否为平方数
在本篇博客中,我们将讨论如何使用有效的算法来判断一个大整数是否为平方数。
给定正整数\(n\),如果存在一个整数\(m\),满足\(m^{2}=n\),那么则称\(n\)为平方数。因此,判断一个大整数\(n\)是否为平方数,很自然的想法就是,从1开始,依次递增,判断这个数的平方是否等于给定的数\(n\),如果是,则\(n\)为平方数,如果这个数的平方大于\(n\),则\(n\)不是平方数。这个想法很简单,但可惜的是,效率却很低,因为我们要遍历\(\sqrt{n}\)个数,当\(n\)很大时,这样的效率是我们不能忍受的。
那么有没有其他方法呢?这时候,一个公式进入我们的视野,那就是:
\]
看上去这个公式给了我们一点希望,因为我们不需要从1开始一个一个去找,而是只需要寻找至\(2\sqrt{n}-1\)即可。但我们仔细地分析一下,不难发现,该公式的实质和一个一个找没什么区别,因为我们还是要遍历\(\sqrt{n}\)个数。
所以,存在有效的算法吗?答案是肯定的!为什么不尝试着去计算\(n\)的平方根呢?按照这个思路,我们具体的算法,结合牛顿法,步骤如下:
- 初始值\(x_0=1\), 误差\(\epsilon\)足够小;
- 按照\(x_{n+1}=\frac{1}{2}(x_{n}+\frac{n}{x_{n}})\)迭代,直至\(|x_{n}^{2}-n|\leq\epsilon\);
- 对\(x_{n}\)取整,结果为\(m\), 如果\(m\)的平方为\(n\),则\(n\)为平方数,否则不是平方数。
接下来,我们证明这个算法的有效性。首先,我们证明对于\(n\geq1\),都有\(x_{n} > \sqrt{n}\)。我们使用数学归纳法。
- 当\(n=1\)时,\(x_{1}=\frac{1}{2}(1+n)>\sqrt{n}\).
- 假设\(x_{n}>\sqrt{n}\),则\(x_{n+1}-\sqrt{n}=\frac{x_{n}^{2}+n-2\sqrt{n}x_{n}}{2x_{n}}=\frac{(x_{n}-\sqrt{n})^{2}}{2x_{n}}>0\),所以\(x_{n+1}>\sqrt{n}\).
接着我们再证明\(x_{n}(n\geq1)\)序列递减。因为当\(n>0\)时,有
\]
这是因为当\(n\geq1\)时,有\(x_{n}>\sqrt{n}\).
因此,我们利用第二步的迭代,不停地运算后,所得到的项\(x_{n}\)与\(\sqrt{n}\)很接近,只是稍微大一点。因此,该算法的第三步的判断就是正确的了。
下面我们将会给出上述算法的Java程序代码,具体如下:
package Problems;
import java.math.BigInteger;
import java.math.BigDecimal;
public class IS_Square {
public static void main(String[] args) {
// 计算2**128+1
BigInteger F7 = new BigInteger("2").pow(128).add(BigInteger.ONE);
boolean w = is_square(F7);
if(w)
System.out.println(String.format("%s是完全平方数。", F7));
else
System.out.println(String.format("%s不是完全平方数。", F7));
}
// 判断是否为完全平方数
public static boolean is_square(BigInteger F7){
// 牛顿法求解平方根, 求解a的平方根
// x为a的平方根,x的初始值为1, 按x = (x+a/x)/2迭代, 误差为error
BigDecimal x = BigDecimal.ONE;
BigDecimal a = new BigDecimal(F7.toString());
BigDecimal eps = new BigDecimal("1");
final BigDecimal error = new BigDecimal("1E-10");
int scale = 100;
// 进入循环
while(eps.compareTo(error) == 1){ // eps > error
x = x.add(a.divide(x, scale, BigDecimal.ROUND_HALF_UP)).divide(new BigDecimal("2.0"), scale, BigDecimal.ROUND_HALF_UP);
eps = x.multiply(x).subtract(a).abs();
}
BigInteger sqrt = x.toBigInteger(); // 求平方根的整数部分
if(sqrt.pow(2).compareTo(F7) == 0)
return true;
else
return false;
}
}
其输出结果如下:
340282366920938463463374607431768211457不是完全平方数。
如果将Java程序中的\(F7=2^{128}\),则输出结果为:
340282366920938463463374607431768211456是完全平方数。
本次分享到此结束,欢迎大家交流~
Java之判断大整数是否为平方数的更多相关文章
- 【Java编程】Java中的大整数计算
在上一篇文章中,我们实现了c语言中的大整数的运算,并且用Miller-Rabin算法实现了对大素数的测试.本来我准备用Java代码实现大整数的运算,查了一下资料发现Java中java.math的Big ...
- 手算平方根和基于 Java BigInteger 的大整数平方根的实现
为了实现任意大数的运算,long用BigInteger替换带哦. 好了废话少数,先说数学原理,也就是手算平方根计算机代码实现!那么什么叫手算平方根了??? 手开方图解 据说前苏联的普通工人都会的(毛熊 ...
- JAVA版拆分大整数为2幂的和算法
import java.util.ArrayList; import java.util.List; public class StrTest { public static void main(St ...
- 很火的Java题——判断一个整数是否是奇数
完成以下代码,判断一个整数是否是奇数: public boolean isOdd(int i) 看过<编程珠玑>的人都知道这道题的答案和其中极为简单的道理. 最普遍的风格,如下: 这个函数 ...
- JAVA题目:正整数n若是其平方数的尾部,则称n为同构数 如:5*5=25, 25*25=625 问: 求1~99中的所有同构数
1 /*题目:正整数n若是其平方数的尾部,则称n为同构数 2 如:5*5=25, 25*25=625 3 问: 求1~99中的所有同构数 4 */ 5 //分析:将1-99分为1-9和10-99,用取 ...
- 每日一练之大整数加法(P1255 数楼梯)
走楼梯走一步还是两步的问题其实就是斐波那契数列(F(n)=F(n-1)+F(n-2),而在int型范围内存在45个相异的数,题干说明楼梯总数可以为5000,则考虑使用字符串进行存储.当两个数相加产生进 ...
- Java 实现大整数加减乘除
自己用Java实现的大整数加减乘除运算.还有可以改进的地方,有兴趣的童鞋可以加以改进.仅供参考,请勿转载! package barrytest; import java.util.ArrayList; ...
- ACM学习之路————一个大整数与一个小整数不得不说得的秘密
这个相对于两个大整数的运算来说,只能说是,low爆了. 只要利用好除法的性质,这类题便迎刃而解.O(∩_∩)O哈哈~ //大整数除一个int数 #include<iostream> #in ...
- 【老鸟学算法】大整数乘法——算法思想及java实现
算法课有这么一节,专门介绍分治法的,上机实验课就是要代码实现大整数乘法.想当年比较混,没做出来,颇感遗憾,今天就把这债还了吧! 大整数乘法,就是乘法的两个乘数比较大,最后结果超过了整型甚至长整型的最大 ...
随机推荐
- ie的用户名密码输入框右侧提示去掉
::-ms-clear,::-ms-reveal{display:none;} //用户名 密码
- kali入门
第一章:入门kalilinux By:鬼尘 第一章基本上就是涵盖以下的主题: ·kali的发展简史 ·kali的一般用途 ·kali的下载与安装 ·kali的配置与更新 在本章结尾部分,我们还会介绍k ...
- 网络操作系统 第九章 DHCP服务器管理与配置
本章小结 本章介绍了DHCP服务器的基本概念,基本原理和主要功能,详细说明了Window是下DHCP服务器的安装配置和Linux下DHCP 服务器的安装配置,通过本章的学习.读者能够理解动态主机配置协 ...
- 《JavaScript 高级程序设计》读书笔记四 变量 作用域 内存
一 变量(基本类型和引用类型) a.基本类型保存值,保存在栈内存,引用类型保存指针,保存在堆内存: b.所有函数的参数都是按值进行传递的,不管参数是何种类型: c.检测类型 typeof ...
- Windows 10 IoT Serials 10 – 如何使用OCR引擎进行文字识别
1. 引言 OCR (Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗.亮的模式确定其形状,然后用字符识别方 ...
- Canal学习笔记(服务端)
canal服务端 canal服务端有两种运行模式,一种单机模式,一种HA运行模式(zk保证) 单机模式:同步的binlog节点信息保存在本地(/conf/{自定义分区文件夹}/),meta.dat H ...
- Javascript高级编程学习笔记(47)—— 元素遍历
元素遍历 为了方便我们使用JS来遍历文档中的元素,W3C在原来的基础之上提出了 Element Traversal 规范 这一规范主要就是为了统一浏览器对文档中节点解析不一致的问题. 比如在某些浏览器 ...
- Vue过渡mode属性踩坑
近期学习Vue的过渡效果的时候,mode属性的"in-out"."out-in"设置了不起作用,官网上的例子让我看了有点迷,问题解决后以此文记录之. 首先我们看 ...
- 吴恩达机器学习笔记14-逻辑回归(Logistic Regression)
在分类问题中,你要预测的变量
- Oracle列转行函数版本不兼容解决方案
业务场景 本博客记录一下Oracle列转行函数在Oracle11的一些不兼容问题,vm_concat在一些业务场景是必须的.不过这个函数使用要谨慎,底层实现应该也是group by等等实现的,性能并不 ...