有关求第n位xxx 的算法的问题
最近,博客园上看到有关求 斐波那契数列的第n位是什么的问题。什么是 斐波那契数列? 我自己也忘记了,后来百度了下。http://baike.baidu.com/view/816.htm?fr=aladdin
现在,了解了什么是 斐波那契数列,到底是什么东西的问题便好做了,不管你是用递归做,还是for 循环,都比较容易想到该如何下手。
可是,问题往往没那么简单。 我在看到这个问题的第一个反应就是——当 int 保存的类型,超出最大值范围后,便得不到自己想求的数值了。
接着可能有人会想到 使用decimal ,可是,经过测试,使用decimal保存的范围也达不到要求(当求第135位左右的时候,超出了可以保存的范围)。
后来想到使用字符串保存第n位数值,进行模拟整数进行计算。 使得尽可能求得更大的范围(尽管这种方式,也受到了,保存的最大字符串个数的限制,但获取范围却大大改善)。
如果有人有更好的方式,欢迎交流。好了,说了那么多,说下具体思路:
1. 使用一个 字符串 string a1保存 第 (n-2)位的数值。(n>=3)
2.使用 string a2 保存 第 (n-1)位的数值。
3. 获取 a1 和a2 的最末尾的数值(看成整数的时候也就是个位数)进行相加, 得到两值相加的和。(此时其中一个为进位,一个为最终值得个位数)
4.循环获取 a1 和a2 的相同位置 (末尾-1) 的数值和进位进行相加。
5. 求第n位的数值,就循环 1至4 的步骤。
说白了,也就是模拟我们动手用笔,进行计算两个数值相加的过程。
好了废话不多说,直接上代码。
private string Plusstring(string str2, string str1)//str1 为字符串个数最多的数值
{ string value = "";
int max = (str1.Length - > str2.Length - ) ? str1.Length - : str2.Length - ; // 较大的字符串个数 int forward = ;// 进位
int k = str2.Length - ; // 较短的字符串
int intvalue = ;
for (int i = max; i > -; i--)
{
if (k > -)
{
intvalue = int.Parse(str1[i].ToString()) + int.Parse(str2[k].ToString()) + forward;// 相同位置的数值相加 所以 intvalue 最大为 9+9+1
k--;
}
else
{
intvalue = int.Parse(str1[i].ToString()) + forward;
}
string strvalue = intvalue.ToString();
value = value.Insert(, strvalue[strvalue.Length - ].ToString());
if (strvalue.Length == ) // 两个数值相加 , 只有一位则 下一个进位 为0 ;
{
forward = ;
}
else
{
forward = int.Parse(strvalue[].ToString());
}
} if (forward != )// 计算完毕,如果进位为0,跳过最高位的进位,否则补回最高位
{
value = value.Insert(, forward.ToString());
}
return value;
}
是通过使用以下代码调用上面的代码进行计算的 。 使用 winform 在上面拖一个 button,一个 textbox
private void button1_Click(object sender, EventArgs e)
{ int n = int.Parse(textBox1.Text.Trim()); // 获取输入第几位
string str1 = "", str2 = "", str3 = "";
decimal a1 = ;
decimal a2 = ;
decimal an = ;
for (int i = ; i < n; i++) // 此处直接计算第三位 之后的数值,第一第二位就不在此增加代码了。
{ // an = a1 + a2;// 此处为使用decimal 与前 130为的数值进行比较看计算出来的数值是否正确。
// a1 = a2;
// a2 = an; str3 = Plusstring(str1, str2);
str1 = str2;
str2 = str3; } MessageBox.Show(string.Format(" n={0}, an={1} , str={2}", n, an, str3)); }
经过测试,很轻松的就计算了 第 1000 位的数值,有木有? 我也试过了计算 第一万位的, 耗时有点长,但还是计算出了结果。十万位的似乎过了半个小时都没算出来。
使用类似的方式,可以计算,什么 1!+2!+。。。+n! 的算法。 相对应的乘法,减法, 只需要在上面的基础上修改一点即可。
可是毕竟还是存在一些问题,这只是扩展了 比较大的范围而已。
例如:
1. 如果我想计算中的数值中, 保存的字符 str1.Length> int.Max 的时候。 便无法正确计算了。
2. 计算除法的时候,一时没想到好的办法,只记得 高中的知识中, 也有类似的方式可以在乘法的基础上进行,计算除法
有关求第n位xxx 的算法的问题的更多相关文章
- 一种快速求fibonacci第n个数的算法
利用动态规则的思路,摒弃传统的递归做法,可以得到一种快速的求fibonacci第n个数的算法: ''' 求第n(从1开始)位fibonacci数 fibonacci数列前两位为0, 1. 后面每一位数 ...
- Hihocder 1639 : 图书馆 (组合数+唯一分解 求最后一位)(妙)
给定n,(n<=10^3),然后输入n的数a[i],(a[i]<=1e10),求ans=(a1+a2+a3...an)! / (a1!*a2!*a3!...an!) 的结果的最一位数. 适 ...
- ipv4 ipv6 求字符串和整数一一映射的算法 AmazonOrderId
字符串和整数一一映射的算法 公司每人的英文名不同,现在给每个英文名一个不同的数字编号,怎么设计? 走ipv4/6 2/32 2/128就够了,把“网段”概念对应到“表或库”,ip有a_e5类,这概念 ...
- Java蓝桥杯练习题——求小数n位后3个数
求整数除法小数点后第n位开始的3位数 位数不足的补0,如0.125小数第3位后三位:0.12500→500 输入格式:a b n,空格分开,a是被除数,b是除数,n是小数后的位置 输出格式:3位数字, ...
- [转载]求平方根sqrt()函数的底层算法效率问题
我们平时经常会有一些数据运算的操作,需要调用sqrt,exp,abs等函数,那么时候你有没有想过:这个些函数系统是如何实现的?就拿最常用的sqrt函数来说吧,系统怎么来实现这个经常调用的函数呢? 虽然 ...
- 相辅相成的求最单源短路径算法:(SPFA& dijkstra)
引用一位老oier的话: 一道题如果边权没有负数,那么一定是在卡SPFA.这时候就用到了堆优化的Dijkstra; 写在前面: 多打代码! 最好都掌握,灵活变通 SPFA: 主要用于稀疏图和有负权边的 ...
- HDU 1025 Constructing Roads In JGShining's Kingdom(求最长上升子序列nlogn算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1025 解题报告:先把输入按照r从小到大的顺序排个序,然后就转化成了求p的最长上升子序列问题了,当然按p ...
- 算法导论(第三版) Exercises4.2(求最大和子数组的算法优化过程)
4.1-1 如所有元素都为负,则返回所有元素中最大的负数. 4.1-2(暴力法求最大和子数组) struct subarray { int start, end, sum; }; void brute ...
- ZOJ 1542 POJ 1861 Network 网络 最小生成树,求最长边,Kruskal算法
题目连接:problemId=542" target="_blank">ZOJ 1542 POJ 1861 Network 网络 Network Time Limi ...
随机推荐
- [转帖]nginx sendfile tcp_nopush tcp_nodelay参数解释
nginx sendfile tcp_nopush tcp_nodelay参数解释 2013-06-25 13:59:40 zmj_88888888 阅读数 20425 文章标签: nginxtcp_ ...
- 2019牛客多校九 I. KM and M (类欧几里得)
大意: 给定$N,M$, 求$\sum\limits_{K=1}^N \text{(KM)&M}$ 考虑第$i$位的贡献, 显然为$\lfloor\frac{KM}{2^i}\rfloor$为 ...
- C#方法(用法,参数)
方法:是一种用于实现可以由对象或类执行的计算或操作的成员,是一个已命名的语句集.方法就是把一些相关的语句组织到一起,用来执行一个任务的语句块.比如每个C#程序至少带一个main函数 1.格式:修饰符 ...
- 怎么将visual studio项目打包生成dll文件
1.打开电脑再打开visual studio软件,在软件里面新建一个项目,文件---->新建---->项目,打开新建项目窗口. 2.选择C#类工程,并为项目命名. 3.将类库文件class ...
- java使用AES-256-ECB(PKCS7Padding)解密——微信支付退款通知接口指定解密方式
1.场景 在做微信支付退款通知接口时,微信对通知的内容做了加密,并且指定用 AES256 解密,官方指定的解密方式如下: 2.导包 <!-- https://mvnrepository.com/ ...
- MySQL库的相关操作
再熟悉一下Mysql库.表.记录的基本操作. 库 增 create database userinfo1 charset utf8; 查 show databases; show create dat ...
- iOS - Scenekit3D引擎初探之 - 给材质贴图
今天简单说一下 SceneKit 给材质贴图. 1,最简单的一种方法,直接打开dae 或者 scn 文件直接设置 如上图,这个dae 文件中只有一个几何体,几何体中只有一个材质球,然后设置材质球的d ...
- $.ajaxSetup()与$.ajax()区别
ajaxSetup()其使用方法与ajax()并无区别,只是在其之后的ajax()不用再重复添加相同参数,节省了代码量. 附:API中关于jQuery.ajaxSetup([options])的描述和 ...
- Java 之 字符输出流[writer]
一.字符输出流 java.io.Writer 抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地. 它定义了字节输出流的基本共性功能方法. void write(int c) ...
- linux文件比较
Linux文件比较指令有两个,comm和diff,其中comm要求的是排序过得文件.Diff则没有这个要求,diff的输出结果主要是用来表明文件一经过怎样的修改可以得到文件二. Comm Comm的语 ...