`
圆圆爸爸
  • 浏览: 14707 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

一个很有趣的编程题

阅读更多
碰巧和一个朋友聊到一个趣题

如何最好最快的方法求阶乘,也就是从1一直乘到n,

怎么样试试吧。




==================================================================================
一个很偶然的机会,谈到一个很有趣的编程题,阶乘的算法,阶乘是从1一直乘到n,刚听
到这个题,觉得很简单,用递归算法就可以搞定了,不过当来写这个代码的时候,才发觉
,原来自己想的过于简单,由于n是不确定的,所以这个数值可能非常的大,远远大于
我们的基本数据类型。那么怎样来表示这个数据结构了,一下就去思考这个方面的问题,
如果是这样想的,那你就是中圈套了,数据结构是根本就解决不了的,只有在算法上做文
章,那么应该是如何的算法了,其实就是最简单的9*9乘法口诀了,就可以搞定了。

觉得很过瘾,特记下来,算法是个很有趣的研究。一个清晰和简洁的算法大有耳目一新的感
觉。
==================================================================================
分享到:
评论
16 楼 brilliant2008 2009-04-17  

public class TestMain {
/*
 * 计算从a到b的连续乘积
 * */
	public static int play(int a, int b) {
		if (a <= b && a > 0 && b > 0) {
			if (b < a) {
				return 1;
			} else {
				return b * play(a, b - 1);
			}
		} else {
			return 1;
		}
	}

	public static void main(String[] args) {
		int a = play(1, 5);
		System.out.println("结果是:"+a);
	}

}
15 楼 kunee 2009-04-07  
哈哈,偶当年这个题目是这样做的。

因为N可能很大,大到计算机基本单元无法存储。

第一部要解决在内存中的问题,用了个字符串数组存几位到几位。

第二步肯定是用加法来做,乘法实在太慢了

第三步,因为在字符串中处理,核心算的那步有一个求余,计算很慢,直接用汇编嵌入计算。。

14 楼 yingwuhahahaha 2009-04-07  
xhanxhanxhan 写道
贴一个自己以前搞ACM时候收藏的代码
求1000! 数据无限大,只要不超过存储空间就行。哈哈。
#include<stdio.h>
long s[1000]={1,1},n=20,t=2,a=1,b=0;
int main()
{
        for(;a<=*s||(++t<=n?(b=0,a=1):0);(*s==a++&&b)?(*s)++:0)
                b+=s[a]*t,s[a]=b%10000,b/=10000;
        for(printf("%d",s[*s]);--*s>0;)printf("%04d",s[*s]);
        return 0;
}

郁闷,没看懂这个循环
13 楼 xhanxhanxhan 2009-04-06  
贴一个自己以前搞ACM时候收藏的代码
求1000! 数据无限大,只要不超过存储空间就行。哈哈。
#include<stdio.h>
long s[1000]={1,1},n=20,t=2,a=1,b=0;
int main()
{
        for(;a<=*s||(++t<=n?(b=0,a=1):0);(*s==a++&&b)?(*s)++:0)
                b+=s[a]*t,s[a]=b%10000,b/=10000;
        for(printf("%d",s[*s]);--*s>0;)printf("%04d",s[*s]);
        return 0;
}
12 楼 night_stalker 2009-04-04  
各种优化算法都写在书上,也没什么好讨论的……

用haskell就很简单,内建无限长整数支持,编译成可执行文件速度也非常快。

我的机器上算60000的阶乘也就几秒钟,和输出结果耗的时间差不多(好长的数字啊)。
factorial 0 = 1
factorial n = n * (factorial (n-1))
main = print (factorial 60000)


最后……其实还有更简单的:
main = print (product [1..60000])



实际应用上,算更大的数的阶乘时,我们往往不需要这么多有效数字,用Stirling公式算出位数就够了。
还有一种情况是算余数的,麻烦点,乘几步求余一次。这两种情况往往都用不着 BigInteger..

速度往往也是没必要的,一般这个东西只算一遍……
11 楼 sunnycare 2009-04-04  
这个优化是一个方面,还有一个方面就是大整数相乘的快速算法。
比如说:
将一个大整数记为(a*10^n+b)*(c*10^n+d)=ac*10^(2n)+db+(ad+bc)*10^n,这样算要4步乘法。(b和d都小于10^n)
你也可以这样算:(a*10^n+b)*(c*10^n+d)=ac*10^(2n)+db+((d-c)(a-b)+ac+bd)*10^n  ,这样只要3步乘法。快了很多。

10 楼 whaosoft 2009-04-03  
这是个什么公司啊 你面的是初级程序员吗??
9 楼 kimmking 2009-04-03  
bonny 写道
阶乘计算是有公式的(近似)

即使这个公式的运算量也是非常的客观。

运算量跟阶乘比 几乎可以忽略~~

kimmking 写道
lshmouse 写道
kimmking 写道
qi是该质数的指数,可以用logpi(N)方法求得


这个是不对的


这个是有确定算法的

int q=0;
while(n>0){
   q+=n/p;
   n=n/p;
}

这个可以~~

如果不要求精确值,阶乘用【Stirling】最简单~~

8 楼 bonny 2009-04-03  
阶乘计算是有公式的(近似)

即使这个公式的运算量也是非常的客观。
7 楼 圆圆爸爸 2009-04-03  
具体的程序编码的伪代码是怎样的了
6 楼 kimmking 2009-04-03  
lshmouse 写道
kimmking 写道
qi是该质数的指数,可以用logpi(N)方法求得


这个是不对的


这个是有确定算法的

int q=0;
while(n>0){
   q+=n/p;
   n=n/p;
}

这个可以~~

如果不要求精确值,阶乘用Stirling最简单~~
5 楼 lshmouse 2009-04-03  
kimmking 写道
qi是该质数的指数,可以用logpi(N)方法求得


这个是不对的


这个是有确定算法的

int q=0;
while(n>0){
   q+=n/p;
   n=n/p;
}
4 楼 圆圆爸爸 2009-04-02  
确实,最后是加法和乘法。
3 楼 kimmking 2009-04-02  
qi是该质数的指数,可以用logpi(N)方法求得


这个是不对的
2 楼 lshmouse 2009-04-02  
我的想法:
(1)最快的方法就是打一个表,然后去查询。就是有点不实际。
(2)1*2*3*....*n = X,那么X=(p1^q1)*(p2^q2)*....*(pk^qk)

k是小于X的质数的个数,pi是第i个质数,

qi是该质数的指数,可以用logpi(N)方法求得

pi^qi可以使用快速幂,复杂度是log2(qi)

回比直接算要快
1 楼 kimmking 2009-04-02  
圆圆爸爸 写道
碰巧和一个朋友聊到一个趣题

如何最好最快的方法求阶乘,也就是从1一直乘到n,

怎么样试试吧。




==================================================================================
一个很偶然的机会,谈到一个很有趣的编程题,阶乘的算法,阶乘是从1一直乘到n,刚听
到这个题,觉得很简单,用递归算法就可以搞定了,不过当来写这个代码的时候,才发觉
,原来自己想的过于简单,由于n是不确定的,所以这个数值可能非常的大,远远大于
我们的基本数据类型。那么怎样来表示这个数据结构了,一下就去思考这个方面的问题,
如果是这样想的,那你就是中圈套了,数据结构是根本就解决不了的,只有在算法上做文
章,那么应该是如何的算法了,其实就是最简单的9*9乘法口诀了,就可以搞定了。

觉得很过瘾,特记下来,算法是个很有趣的研究。一个清晰和简洁的算法大有耳目一新的感
觉。
==================================================================================

lz很强悍啊,
-------------------
文章: 0
积分: 70
来自: 深圳

相关推荐

    第十届蓝桥杯大赛青少年创意编程Scratch组国赛编程题.zip

    《第十届蓝桥杯大赛青少年创意编程Scratch组国赛编程题》是一个针对青少年编程爱好者的重要赛事资源包,其中包含了历年来蓝桥杯大赛Scratch组的国赛编程题目。Scratch是麻省理工学院(MIT)媒体实验室“终身幼儿园...

    C++趣味编程题(含答案).doc

    《C++趣味编程题》是一份集合了多个有趣编程挑战的文档,主要针对C++语言进行设计。这些题目旨在帮助学习者提升C++编程技能,同时增加编程的乐趣。本题库涵盖不同难度级别的问题,适合不同程度的C++学习者。 在提供...

    最新JAVA-编程题(50题及答案).pdf

    为了深入理解Java并将其应用于实际的编程任务中,解决具体的编程题是一个非常有效的学习方法。本文将为您详细解析《最新JAVA-编程题(50题及答案).pdf》中精选的几个编程题目,这些题目覆盖了从基本算法到复杂逻辑的...

    JAVA编程题全集(50题及答案).pdf

    ### JAVA编程题全集知识点概览 #### 知识点一:菲波那契数列(程序1) **描述:** 本程序通过计算每个月兔子的数量,实际上是在解决一个经典的数学问题——菲波那契数列问题。菲波那契数列是一个著名的数列,其...

    Java编程题全集(50题及答案)

    第三题是寻找“水仙花数”,这是一个涉及循环和条件判断的有趣问题。所谓水仙花数,指的是一个三位数,其各位数字的立方和等于该数本身。例如:153 = 1^3 + 5^3 + 3^3。这道题目将引导初学者熟悉循环结构在数字处理...

    编程题记录.docx

    本文档中收录的四个编程题的解决方案,不仅为初学者提供了一个动手实践的平台,而且为进阶者提供了一个巩固和深化理解的机会。通过这些练习,我们能够更加深入地掌握C语言的精髓,以及编程思维在解决实际问题中的...

    编程题:寻宝游戏

    总的来说,这个寻宝游戏项目涵盖了基础的编程概念,为初学者提供了一个有趣的实践平台,同时对有经验的开发者来说,也是一个重温基础知识和提升编程技巧的好机会。通过深入研究源代码,我们可以更深入地理解编程语言...

    JAVA编程题全集(50题及答案)

    在编程中实现斐波那契序列生成器是一个很好的练习,它能够帮助我们理解循环结构和递归的使用。通过编程解决兔子繁殖问题,我们不仅能够学会如何使用循环来解决数学问题,而且还可以锻炼我们的逻辑思维能力。 接下来...

    Arduino蓝桥杯第十一届省赛试题(编程题9道)

    1. **Arduino基础知识**:Arduino 是一个开源硬件和软件平台,允许用户通过编写简单的代码来控制各种电子元件。它提供了易于理解的编程环境和丰富的库,使得初学者也能快速上手。 2. **Mixly介绍**:Mixly 是一款...

    最新JAVA编程题全集(50题及答案)

    本题通过一个有趣的兔子繁殖问题引入了菲波那契数列的概念。 **知识点解析:** 1. **菲波那契数列定义**:菲波那契数列是这样一个数列:0, 1, 1, 2, 3, 5, 8, 13, 21, ...。除了前两项外,每一项都是前两项的和。 2...

    Chrome插件-《Astro Bot》用新标签页刷编程题.zip

    《Astro Bot》是一款专为程序员设计的Chrome浏览器插件,它创新性地将编程题和相关新闻融入到浏览器的新标签页之中,旨在帮助用户在浏览网页的同时,保持学习和提升编程技能的习惯。这款插件的独特之处在于其...

    SQL编程习题与解答.pdf

    SQL编程习题与解答 SQL编程相关的有趣问题,涉及数据库应用的许多方面,如财务、投资、旅游、销售、...针对每一个谜题,作者给出了基于SQL-99及更新标准的多种解决方案,展示了解题思路,对SQL程序员有很强的参考价值。

    最新JAVA编程题全集(50题及答案).

    水仙花数是一个有趣的数学概念,指的是一个三位数,其各位数字的立方和等于该数本身。这类题目不仅考验了编程者对数学知识的了解,更是检验其循环和条件判断等基础操作的灵活运用。通过三层嵌套循环(外层控制百位数...

    2019《青少年编程能力等级》测试真题(图形化编程一级)

    2019年全国青少年编程能力等级测试的图形化编程一级真题卷,提供了孩子们检验自己学习成果的机会,同时也为他们提供了一个实战演练的平台。通过解答这些真题,孩子们可以发现自己在编程理解、逻辑思维和问题解决方面...

    浪潮集团编程大赛样题

    【编程大赛概述】 编程大赛是IT行业内一种常见...总的来说,"第一届浪潮集团编程大赛"为参赛者提供了一个展示和提升自身编程能力的平台,通过深入学习和实践,不仅可以提升技术水平,还有可能为职业生涯打开新的机会。

    经典java编程50题

    下面将对这四道典型的Java编程题进行详细分析,旨在帮助初学者深入理解Java编程的基础知识。 #### 1. 菲波拉契数列问题 **问题解析**: 菲波拉契数列是数学中一种非常有趣的序列,每一项都是前两项的和,例如:0, ...

    100Java 有趣的逻辑题 新颖 有趣 最全

    100Java 有趣的逻辑题 新颖 有趣 最全

Global site tag (gtag.js) - Google Analytics