python 如何求N的阶乘
作者:好心boy 发布时间:2023-11-01 15:24:46
求N的阶乘
本题要求编写程序,计算N的阶乘。
输入格式:
输入在一行中给出一个正整数 N。
输出格式:
在一行中按照“product = F”的格式输出阶乘的值F,请注意等号的左右各有一个空格。题目保证计算结果不超过双精度范围。
输入样例:
5
输出样例:
product = 120
x = int(input())
a = 1
for i in range(1, x+1):
a = a*i
print("product = %d" % float(a))
实现阶乘的三种解法
问题描述:
输入一个正整数n,输出n!的值。
其中n!=123*…*n。
算法描述:
n!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。使用一个数组A来表示一个大整数a,A[0]表示a的个位,A[1]表示a的十位,依次类推。
将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。
首先将a设为1,然后乘2,乘3,当乘到n时,即得到了n!的值。
输入格式:
输入包含一个正整数n,n<=1000。
输出格式:
输出n!的准确值。
样例输入:
10
样例输出:
3628800
看到这题我首先想到的是两种比较简单的解法,一是循环,二是递归。
解法一:循环
n = int(input())
ns = 1
for i in range(1,n+1):
ns = ns*i
print(ns)
思路比较简单,就是定义一个变量ns赋予一个初始值1,然后利用for循环直接累乘得到最终结果。
解法二:递归
def factorial(n):
if n==1:
return n
else:
return n*factorial(n-1)
n = int(input())
res = factorial(n)
print(res)
递归也比较好理解,当n == 2,return 2 * 1;n == 3,return 3*(2 * 1);n==4,return 4*(3*(2*1))。以此类推,再将最终的结果赋予res将其打印即可。
这两种方法都比较简单,但很显然都不符合题目要求的 “使用一个数组A来表示一个大整数a,A[0]表示a的个位,A[1]表示a的十位”,所以我们要想办法利用数组来得到n!的结果。
解法三:数组
n= int(input())
ns = [0 for i in range(10000) ]
length = 1
ns[0] = length = 1
if n>=2:
for i in range(2,n+1):
carry = 0
for j in range(length):
temp = ns[j] * i + carry
carry = int(temp/10)
ns[j] = temp % 10
while carry>0:
ns[length] += carry%10
length+=1
carry = int(carry/10)
while length>0:
length -=1
print(ns[length],end='')
接下来我讲下思路:
首先定义一个ns数组用来存储n!的各个位数上的数值,利用for循环给ns加入10000个0值,以方便后面直接根据index对数组进行操作。
然后定义length作为 “数组的长度”(有真实数值的而非自动添加的0) 也即n!的结果的位数。
之后也必须用到for循环进行累乘,但跟解法一的直接累乘不同,这里是乘数(即i)跟各个位上的数分别相乘,若结果大于等于10则carry>0即向前进一位数值为carry,若j循环结束后carry>0则说明需要在当前ns的“长度”上进一位,所以length+1即位数+1,这里carry起的就是判断是否进位的作用,而length则代表着结果的位数。可能这么说有些抽象,下面我们通过分解运行过程来更直观的阐述上面的想法。
例如我们现在需要求5!,分五步,即i循环5次:
①i=1
ns[0] = length =1 , carry = 0
∴j in range(1)
⑴ j=0
temp = ns[j] * i + carry = ns[0] * i + carry =1*1+0=1 # temp为第j位数与i相乘并加上j-1位数与i相乘后进位的值的结果
carry = int(temp/10) = 1/10 = 0 # carry=0所以不用进位
ns[j] = temp % 10 即 ns[0] = 1 % 10 =1 #只取个位数值作为第j位的值
②i=2
ns[0] = 1, length =1 , carry = 0
∴j in range(1)
⑴ j=0
temp = ns[j] * i + carry = ns[0] * i + carry =1*2+0=2 # temp为第j位数与i相乘并加上j-1位数与i相乘后进位的值的结果
carry = int(temp/10) = 2 / 10 = 0 # carry=0所以不用进位
ns[j] = temp % 10 即 ns[0] = 2 % 10 =2 #只取个位数值作为第j位的值
#这样就已经的到2!的值了即2
③i=3
ns[0] = 2, length =1 , carry = 0
∴j in range(1)
⑴ j=0
temp = ns[j] * i + carry = ns[0] * i + carry =2*3+0=6 # temp为第j位数与i相乘并加上j-1位数与i相乘后进位的值的结果
carry = int(temp/10) = 6 / 10 = 0 # carry=0所以不用进位
ns[j] = temp % 10 即 ns[0] = 6 % 10 =6 #只取个位数值作为第j位的值
#这样就已经的到3!的值了即6
④i=4
ns[0] = 6, length =1 , carry = 0
∴j in range(1)
⑴ j=0
temp = ns[j] * i + carry = ns[0] * i + carry =6*4+0=24 # temp为第j位数与i相乘并加上j-1位数与i相乘后进位的值的结果
carry = int(temp/10) = 24 / 10 = 2 # carry=2>0所以需要向前进2
ns[j] = temp % 10 即 ns[0] = 24 % 10 =4 #只取个位数值作为第j位的值
j循环结束,carry>0执行while循环
while carry>0:
ns[length] += carry%10 即 ns[1] += 2 % 10 = 2 #carry = 2 所以向前进2
length+=1 即 length =1+1=2 #位数加一
carry = int(carry/10) = 2 / 10 = 0 # carry = 2<10所以不需要继续进位,while循环结束
∴length = 2 , ns[0] = 4 ,ns[1] = 2
#这样就得到4!的值ns[1]*10+ns[0] 即 24,输出时可直接倒着打印然后end=''而不需要每位数乘10*n再相加
⑤i=5
ns[0] = 4, ns[1] = 2 length =2 , carry = 0
∴j in range(2)
⑴ j=0
temp = ns[j] * i + carry = ns[0] * i + carry =4*5+0=20 # temp为第j位数与i相乘并加上j-1位数与i相乘后进位的值的结果
carry = int(temp/10) = 20 / 10 = 2 # carry=2>0所以需要向前进2
ns[j] = temp % 10 即 ns[0] = 20 % 10 =0 #只取个位数值作为第j位的值
⑵ j=1
temp = ns[j] * i + carry = ns[1] * i + carry =2*5+2=12 # temp为第j位数与i相乘并加上j-1位数与i相乘后进位的值的结果
carry = int(temp/10) = 12 / 10 = 1 # carry=1>0所以需要向前进1
ns[j] = temp % 10 即 ns[1] = 12 % 10 =2 #只取个位数值作为第j位的值
j循环结束,carry>0执行while循环
while carry>0:
ns[length] += carry%10 即 ns[2] += 1 % 10 = 1 #carry = 1 所以向前进2
length+=1 即 length =2 +1 = 3 #位数加一
carry = int(carry/10) = 1 / 10 = 0 # carry = 1<10所以不需要继续进位,while循环结束
∴length = 3 , ns[0] = 0 , ns[1] = 2 , ns[2] = 1
# 这样就得到5!的值ns[2] ns[1] ns[0]即 120
这样看下来是否发现和小学的时候学的竖式乘法运算过程很相似,从低位数到高位数(ns[j],j in range(0,length))依次与乘数(i)相乘,大于十则进位(carry=temp/10>0,若ns[length]*i+carry > 10则length+1)。
来源:https://blog.csdn.net/sinat_28502161/article/details/86531416
猜你喜欢
- 看了山人表单验证,又看了其他一些验证程序和相关的一些参考资料,写出了一个比较简洁的js表单验证程序。特点是扩展容易,可以方便的添加自己需要的
- 本文只有代码,介绍了有关GUI界面的学生信息管理系统的实现。已经过调试没有很大问题。如有错误,还请批评指正。1.导入tkinter模块imp
- 首先从 ueEditor官网 下载最新版本的包,目前官网上提供了ASP、.NET、PHP、JSP版本的,django版本只有一个第三方个人开
- 对于手机、相机等设备拍摄的照片,由于手持方向的不同,拍出来的照片可能是旋转0°、90°、180°和270°。即使在电脑上利用软件将其转正,他
- Python中的数据类型共有六个,分别是:字符串,数字,布尔类型,列表,元祖,字典,集合其中分为可变的类型和不可变的:可变类型:列表,字典,
- cookie:PHPSESSID=et4a33og7nbftv60j3v9m86cro; Hm_lvt_51e3cc975b346e7705
- 平台:windows 10pycharm 2016.2python 2.7.12问题始于我在pycharm下建了一个flask工程,然后导入
- 当创建一个Models, 在同步到数据库里,django默认设置了三个权限 ,就是 add, change, delete权限。但是往往有时
- 阅读目录什么是设计模式单体模式:工厂模式:单例模式观察者模式(发布订阅模式)策略模式模板模式代理模式外观模式设计模式太多了,貌似有23种,其
- yield的功能类似于return,但是不同之处在于它返回的是生成器。生成器生成器是通过一个或多个yield表达式构成的函数,每一个生成器都
- InnoDB和MyISAM是在使用MySQL最常用的两个表类型,各有优缺点,视具体应用而定。下面是已知的两者之间的差别,仅供参考。1.Inn
- 这篇文章主要介绍了python框架flask表单实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- 在python中可以根据字符串来调用函数:1、使用getattr从字符串来调用函数在多进程中,可能传递过来的是一个字符串,那么我怎么来调用一
- 1、什么是哈希hashhash一类算法,该算法接受传入的内容,经过运算得到一串hash值hash值的特点:只要传入的内容一样,得到的hash
- 前言scikit-learn是Python中最流行的机器学习库之一,它提供了各种各样的机器学习算法和工具,包括分类、回归、聚类、降维等。sc
- 软件版本Python 2.7.13; Win 10场景描述1、使用python读取指定长度的文本;2、使用python读取某一范围内的文本。
- 前面也讲过一次phar文件上传的东西,但是那都是过滤比较低,仅仅过滤了后缀。知道今天看到了一篇好的文章如果过滤了phar这个伪造协议的话,那
- 前言网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或
- 在模板中往往要加载静态文件,如CSS, JavaScript,图片等。那么这些文件在django中如何才能正确加载呢?首先要在setting
- 前言时隔108天,何同学在B站发布了最新的视频,《【何同学】我用108天开了个灯…》。那么就让我们用爬虫,爬取视频的弹