(.NET)利用二分查找实现任意整数的开方运算
群里面有人传了一道面试题,大致意思就是求任意整数的开方运算。
public static string Squre(int input) { if (input == 0) { return "0"; } if (input < 0) { input = input * (-1); } double min = 0; int i = 0; while (true) { i++; if (i * i == input) { return i.ToString(); } if (i * i >= input) { min = i - 1; int count = 0;
//我是关键 //这里可以用for循环来实现,但是for的效率。。。。运行个几万十万次都很正常 Console.WriteLine("=========================手写========================"); Console.WriteLine("手写次数:" + count); return input < 0 ? s : s + "i"; } } }
while(true)中的意思是我求出所有的正整数的平方与输入的数字进行比较,
比如,我们求5的开方,那么5的开方肯定在2*2与3*3之间,那么结果肯定就是2-3之间的
某个数,使用for循环的话,需要从2加个精度的小数一直加到x*x>input为止,那么,
在某些情况下for循环执行的次数肯定是我们不希望的,所以下面放出递归代码:
关键部分调用:
string s = Find(min, input, 1, ref count).ToString();
public static double Find(double min, int input, double x, ref int count) { count++; double m = (min + x / 2) * (min + x / 2); double result; if (m > input) { if (m - input < 0.000000000001) { result = min + x / 2; return result; } else { return Find(min, input, x / 2, ref count); } } else if (m < input) { if (input - m < 0.000000000001) { result = min + x / 2; return result; } else { return Find(min + x / 2, input, x / 2, ref count); } } else { result = min + x / 2; return result; } }
使用一个递归来,运行次数只有几十次就可以得出结果,运行效率极大提高,来测试下:
static void Main(string[] args) { Thread.Sleep(1000);//怕程序启动的时候对下面的运行有影响 Stopwatch sp = new Stopwatch(); Console.WriteLine("=========================自带========================"); sp.Start(); Console.WriteLine("math:" + Math.Sqrt(9999999)); sp.Stop(); Console.WriteLine("用时:" + sp.ElapsedMilliseconds); sp.Restart(); Console.WriteLine("手写:" + Squre(9999999)); sp.Stop(); Console.WriteLine("用时:" + sp.ElapsedMilliseconds); Console.ReadKey(); }
结果如下:
=========================自带======================== math:3162.27750205449 用时:0 =========================手写======================== 手写次数:39 手写:3162.27750205449 用时:1
我自己测试了很多次,有些时候运行时间比math多,有些时候比math少;
递归的主要思路:
input肯定是位于min和max之间某个数的平方,那么取min和max的中间数的
平方与input比较,如果大于input那么,在(min+(max-min)/2)到max之间就存在一个
数的平方等于input,接下来继续判断,如果第二次调用find,还是大于input,那么,
在((min+(max-min)/2)+(max-(min+(max-min)/2))/2)到max之间可以找到这个数,依次,
一直找到我们代码中所写的条件为止就ok了。
浙公网安备 33010602011771号