大数的阶乘(n!)

大数的阶乘(n!)
大数的阶乘(n!)

信息科学与工程学院

编程设计实验文档

题目:较大数的阶乘

一、设计目的:

1.解决一般大数的阶乘问题,可以避免一般算法实行时的数据溢

出的弊端

2.培养自己对算法的理解,提高自身的水平

3.熟练对c语言的操作,加强对c语言的理解

二、设计分析:

实现一般较小的数的阶乘,可以直接利用普通的乘法进行循环

运算即可,即利用s=n*(n-1)的核心算法。但是,当n比较

大的时候,会造成运算的结果,即s会变得特别大,便会造成

数据溢出。此时,就需要另一种算法,是结果可以保存,不溢

出。那么,这个算法就是要解决这个问题,所以,我想到另一

方式用来解决这个问题,即利用数组。

如下:

首先,定义两个整型的数组:

int a[200];//暂且先设定是200位,我称之为“结果数组” int add[200];//我称之为“进位数组”

现在具体说明两个数组的作用:

1.a[200]

比如说,一个数5的阶乘是120,那么我就用这个数组存储它: a[0]=0

a[1]=2

a[2]=1

因此,用这样的数组我们可以放阶乘后是200位的数

2.在介绍add[200]之前,我介绍一下算法的思想,就以6!为

例:

从上面我们知道了5!是怎样存储的。

就在5!的基础上来计算6!,演示如下:

fac[0]=fac[0]*6=0

fac[1]=fac[1]*6=12

fac[2]=fac[2]*6=6

3.现在就用到了我们的:“进位数组”add[1000].

先得说明一下:add[i]就是在第2步中用算出的结果中,第

i位向第i+1位的进位数值。还是接上例:

add[0]=0;

add[1]=1; // 计算过程:就是 (a[1]+add[0]) % 10=1 add[2]=0; // 计算过程:就是 (a[2]+add[1]) % 10=0

.......

.......

.......

add[i+1] =( a[i+1] + add[i] ) % 10

三、算法流程图

四、主要模块功能及程序说明

本程序主要分为三个模块,第一个模块就是判断输出是否错误,当输入的数据是小于1的时候,程序的输出结果是显示“输入

错误;第二个模块当输入正确时模拟一个乘法的运算,先算出

该数的阶乘是多少兵保存在a[200]这个数组中;第三个模块

根据所得结果位数的判断如何按4个数字一组的输出这个数,

当所得结果为4的倍数时,我选择的是单独输出末尾四个数,

剩下的按“1234,”这样的形式输出,当所得结果不是4的倍

数时,我选择优先输出前面的几个数,把后面的数字按四个一

组“,1234”这样的形式输出。

五、实验结果:

1.当输出的数字小于0的时候

2.当输入的数所得的结果是4的倍数时,如输入11时

3.当输入的数所得的结果不是4的倍数时,如15

附录

A变量及函数功能说明

n是输入的数据

S是输出结果的位数除以4所得的余数

t是输出结果的位数除以4所得的商值

a[200]是用来保存最后结果的数组

temp为阶乘的任一元素与临时结果的某位的乘积结果digit表示所得结果的位数

carry表示进位

B.源程序代码

#include

int main()

{

int n,s,t;

int a[200];

int carry;

int digit=1;

int temp,i,j;

scanf("%d",&n);

a[0]=1;

if(n<1)

printf("输入错误/n");

else

{

for(i=1;i<=n;++i)

{

for(j=1,carry=0;j<=digit;++j)

{

temp=a[j-1]*i+carry;

a[j-1]=temp%10;

carry=temp/10;

}

while(carry)

{

a[++digit-1]=carry%10;

carry/=10;

}

}

t=digit/4;

s=digit%4;

if(s==0)

{

for(i=t;i>1;i--)

printf("%d%d%d%d,",a[4*i-1],a[4*i-2],a[4*i-3],a[4*i-4]);

printf("%d%d%d%d",a[3],a[2],a[1],a[0]);

}

else

{

for(i=digit-1;i>=digit-s;i--)

printf("%d",a[i]);

for(i=t;i>0;i--)

printf(",%d%d%d%d",a[4*i-1],a[4*i-2],a[4*i-3],a[4*i-4]); }

}

}

阶乘运算

//阶乘各算法的 C++ 类实现 #include #include #include #include using namespace std; class Factorial { static const int MAXN = 5001; // 最大阶乘数,实际用不到这么大int *data[MAXN]; // 存放各个数的阶乘 int *nonzero; // 从低位数起第一个非0数字 int maxn; // 存放最大已经计算好的n的阶乘int SmallFact(int n); // n <= 12的递归程序 void TransToStr(int n, int *s); // 将数n倒序存入数组中 void Multply (int* A, int* B, int* C, int totallen); // 执行两个高精度数的乘法public: Factorial(); ~Factorial(); void Calculate(int n); // 调用计算阶乘 int FirstNonZero(int n); // 返回阶乘末尾第一个非0数字int CountZeros(int n); // 返回阶乘末尾有多少个0 int SecondNum(int n); // 返回阶乘左边的第二个数字 bool CanDivide(int m, int n); // 判断数值 m 是否可以整除 n! void Output(int n) const; }; int Factorial::SmallFact(int n) { if (n == 1 || n == 0) return 1; return SmallFact(n-1)*n; } void Factorial::TransToStr(int n, int *tmp) { int i = 1; while (n) { tmp[i++] = n%10; n /= 10; } tmp[0] = i-1; } void Factorial::Multply (int* A, int* B, int* C, int totallen) { int i, j, len; memset(C, 0, totallen*sizeof(int));

阶乘的计算和处理程序设计

阶乘的计算及处理程序设计 一、问题描述 要求输入一个自然数n,求n!,同时统计结果中有几个0。 二、课题分析 1)计算n!。 2)统计0的个数。 三、数据结构的设计 x:输入的数n i:n! b:储存数据i上的各位上的数,从而判断b是否为0 j:统计0的个数 四、处理结构的设计 建立两个函数f1和f2,使f1函数起到求阶乘的作用,f2函数起到求0个数的作用。

求阶乘流程图

计算0的个数流程 五、源程序 1)主要结构体: f1函数: long int f1(int x) { long int i; //声明长整型变量i if (x==0||x==1) //采用递归函数f1求阶乘i=1; else i=f1(x-1)*x; return (i); }

f2函数: int f2(int i) {int j=0; int b=0; while(i>=10) //循环结构,判断末位是否为零,再去末位{b=i %10; if(b==0)j++; i=i/10; } return (j); } 2)整体: #include long int f1(int x) { long int i; if (x==0||x==1) i=1; else i=f1(x-1)*x; return (i); } int f2(int i) {int j=0; int b=0; while(i>=10) {b=i %10; if(b==0)j++; i=i/10; } return (j); } void main() {long int f1(int x); int f2(int x); long int k; int n,i; printf("please input n:"); scanf("%d",&n); k=f1 (n); i=f2 (k); printf("%d! is %ld\nthere are %d zero!\n",n,k,i);

N阶乘的递归调用展开式

long fact(int n) 1 { 2 long k; 3 if (n<0) 4 { 5 printf( “Data error!\n”); 6 exit(0); 7 } 8 else if (n==0||n==1) k=1; 9 else k=n*fact(n-1); 10 return k; 11 } main() { int n; long f; printf(“Please input an integral number:\n”); scanf(“%d”, &n); f=fact(n); printf(“%d!=%ld\n”, n, f); }

求fact(4)的详解过程, 执行了的语句用红色表示long fact(4) 1 { 2 long k; 3 if (4<0) 4 { 5 printf( “Data error!\n”); 6 exit(0); 7 } 8 else if (4==0||4==1) k=1; 9 else k=4*fact(4-1); /*断点1:调用fact(3)*/ 10 return k; 11 }

long fact(3) 1 { 2 long k; 3 if (3<0) 4 { 5 printf( “Data error!\n”); 6 exit(0); 7 } 8 else if (3==0||3==1) k=1; 9 else k=3*fact(3-1); /*断点2:调用fact(2)*/ 10 return k; 11 }

long fact(2) 1 { 2 long k; 3 if (2<0) 4 { 5 printf( “Data error!\n”); 6 exit(0); 7 } 8 else if (2==0||2==1) k=1; 9 else k=2*fact(2-1); /*断点3:调用fact(1)*/ 10 return k; 11 }

计算N的阶乘

北华航天工业学院 课程设计报告(论文) 设计课题:计算N的阶乘 专业班级: 学生姓名: 指导教师: 设计时间:2010年12月16日

北华航天工业学院电子工程系 微机原理与接口技术课程设计任务书 指导教师:刘金梅教研室主任: 2010年12 月18 日

内容摘要 本次课程设计编写计算N!的程序。数值N由键盘输入,结果在屏幕上输出,通过编制一个阶乘计算程序,了解怎样在汇编语言一级上实现高级语言中的数学函数。其难点在于随着N的增大,其结果远非寄存器所能容纳。这就必须把结果放在一个内存缓冲区中。然而乘法运算只限于两个字相乘,因此要确定好算法,依次从缓冲区中取数,进行两字相乘,并将DX中的高16位积作为产生的进位。 索引关键词:N的阶乘汇编语言内存缓冲区

目录 序言————————————————————5 正文————————————————————5 一、程序算法————————————————-—-5 二、源程序—————————————————-—-6 三、程序运行与调试—————————————-—11 四、N的阶乘程序流动图——————————-—-—11 心得体会——————————————————13 参考文献——————————————————13

序言 本文是关于微型计算机原理写文件课程设计。编写程序,将内存区域中用调试程序(DEBUG)设置好的一连串数据(以Ctrl+z为结束符)做为一个文件存入磁盘,文件名为DATA.ASM。内存区域的段地址和偏移地址在程序中输入。 随着计算机的高速发展,微型计算机已经应用到各个领域,微型计算机原理应用技术已经成为电子信息的核心产业。 微型计算机原理是计算机科学与技术、通讯工程、电气工程、机电工程的核心课程。 通过这次课程设计,是我们更好地理解了课程中所学的理论知识,并把实际问题转化为理论知识,学会如何把学到的知识用于解决实际问题,培养我们的动手能力。 正文 一、程序算法 阶乘的定义为N!=N(N-1)(N-2)……2,从左至右依次计算,结果保存在缓冲区BUF中。缓冲区BUF按结果由高到低依次排列。程序首先将BP初始化为N,N 不等于0或1则将N送入BUF缓冲区最低字节单元中。然后使BP为N-1,以后BP依次减1,直到变化为1为止。每次让BP与BUF中的字节单元按由低到高的次序相乘。低位结果AX仍保存在相应的BUF字节单元中,高位结果DX则送到进位字单元CY中,作为高字相乘时从低字来的进位,初始化CY为0.计算结果的长度随着乘积运算而不断增长。由字单元LEN指示。LEN单元初始化为1。当最高字单元与BP相乘时。若DX不为0,则结果长度要扩展。

大数阶乘与快速排序算法(汇编)

微机原理 课程设计说明书设计题目:大数阶乘与排序 专业 班级 学生 指导教师 2014 年春季学期

目录 目录 (1) 一.课设目的与要求 (2) 1.课设目的 (2) 2.题目要求 (2) 二.基本原理 (2) 1.大数阶乘原理设计 (2) 2.排序原理设计 (2) 三.架构设计 (2) 四.方案实现与测试 (3) 五.分析总结 (9) 六.参考文献 (9)

一.课设目的与要求 1.课设目的:检验和提高学生在汇编语言程序设计,微机原理与接口应用方面分析问 题与解决问题的能力 2.题目要求: 1).要求实现用汇编语言编写设计一个求解大数的阶乘精确值的程序;采用字节型数组 存放阶乘结果的每个数字位,采用逐位相乘,再对每一位规格化来实现;输出结成结果的位数及尾零的个数。 2).用汇编语言编写设计快速排序与希尔排序程序,注意合理使用堆栈,以避免堆栈溢 出,进一步动态显示排序过程。 二.基本原理 1.大数阶乘原理设计:我们在处理一个大于一定范围的数的阶乘时,无论使用什么类型去保存运算结果都必然会发生溢出,这势必会导致运算结果出错。使用数组来模拟数字,这样无论结果数字有多大,只要数组的长度够长就能表示出来,用这个办法可以进行大数据的运算。 2.排序原理设计:快速排序原理:首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。 三.架构设计 核心思想就是把计算结果每一位上的数字保存到一个数组成员中,例如: 把112保存至数组中,保存结果应该是 result[0] 2 result[1] 1 result[2] 1 把整个数组看成一个数字,这个数字和一个数相乘的时候,需要每一位都和这个乘数进行相乘运算还需要把前一为的进位加上。运算方法和小学数学是一样的,乘积的个位是当前位上应该表示的数字,10位以上的需要进位。因为乘数不可能大于10000,所以乘数和一个小于10的书相乘的时候不会大于100000,再加上前一位的进位用一个int型数据来保持这个结果就没有问题。写法如下: int 结果= result[x] * 乘数+ 进位; 每一位的计算结果有了,把这个结果的个位数拿出来放到这个数组元素上: result[x] = 结果%10; 接下来的工作就是计算出进位: 进位= 结果/ 10; 这样一位一位的把整个数组计算一遍,最后可能还有进位,用同样的方法,把进位的数值拆成单个数字,放到相应的数组元素中。

大数的阶乘

大数的阶乘 众所周知,阶乘的定义就是n! = (n-1)!*n,但是有基本的初始条件的,即0! = 1 因此1! = 1*0! = 1 * 1 = 1; 2! = 2*1! = 2 * 1 = 2; 依次类推,但是当n足够大时,整型根本无法装下n的阶乘,如果用C语言来实现的话,根本不可能,那怎么办呢? 其实阶乘也无非是乘法和加法罢了,如4!= 24;我们可以用数组来存各位,结舌数组的起始长度是1哈,每当遇到超过长度时,就自加1,不过这里要稍微处理下的,我们可以倒过来存,以便做乘法的,可以这样来存。 4! 4 2 5! = 5 * 4!,可以用5去乘以4,如果大于10则需向高位进位,下一位的结果就等于下一位乘以5然后加上刚才的进位,当然也要取余数哈,然后继续看有没进位哈,知道遍乘数组每一位哈。 给个能求1000!的例子,用C语言实现的,供大家参考,以便交流学习哈。 #include using namespace std; #define N 1000 // 所需求的N的阶乘 static int a[N*3]; // 保存阶乘的各位 int main() { int i,j; //临时变量 int len = 1; int tem,carry; a[1] = 1; //1的阶乘 for (i = 2;i<=N;i++) //求阶乘的方法 { carry = 0; for (j=1;j<=len;j++) { tem = a[j]*i +carry; a[j] = tem%10; carry = tem/10; if (j==len&&carry!=0) { len++; } } } for (i = len;i>=1;i--) //输出各位 { cout<

数据结构概述

教材:《数据结构》严蔚敏吴伟民清华大学出版社 《数据结构算法实现及解析》高一凡西安电子科技大学出版社 第一部分数据结构概述 一、定义(研究是数据结构的存储和数据的操作的) 如何把现实中大量而复杂的问题以特定的数据类型和特定的存储结构保存到主存储器(内存)中,以及在此基础上为实现某个功能(比如查找某个元素,删除某个元素,对所有元素进行排序)而执行的相应操作,这个相应的操作也叫做算法。 数据结构= 个体的存储(从某个角度而言,可忽略)+ 个体与个体之间关系的存储(核心) 算法= 对存储数据的操作 二、算法 解题的方法和步骤 衡量算法的标准 1.时间复杂度 大概程序要执行的次数,而非执行的时间 2.空间复杂度 算法执行过程中大概所占用的最大内存 3.难易程度(即可读性) 4.健壮性 三、数据结构的地位 数据结构是软件中最核心的内容 程序= 数据的存储+ 数据的操作+ 可以被计算机执行的语言 第二部分预备知识 一、指针

指针的重要性:指针是C语言的灵魂 定义 地址:内存单元的编号 从零开始的非负整数 范围:0--FFFFFFFF(即0--4G-1) 指针: 指针就是地址,地址就是指针 指针变量是存放内存单元地址的变量 指针的本质是一个操作受限的非负整数(只能进行减运算)分类: 1.基本类型的指针 2.指针和一维数组的关系 二、结构体 为什么会出现结构体 为了表示一些复杂的数据,而普通的基本类型变量无法满足要求什么叫结构体 结构体是用户根据实际需要自己定义的数据类型 如何使用结构体 两种方式: struct Student st = {1000, "zhangsan", 20} struct Student * pst = &st; 1.st.sid 2.pst->sid pst所指向的结构体变量中的sid这个成员

关于阶乘的程序编写

数的阶乘 很多教材中的阶乘程序只是简单地用了阶乘的定义,算法比较简单,考虑也不够全面,其相应的程序如下: /* 数的阶乘(经典版)*/ #include"stdio.h" main() { extern jiecheng(int n); int n; printf("请输入一个数:"); scanf("%d",&n); jiecheng(n); } extern jiecheng(int n) { long result=1; int i; for(i=1;i<=n;i++) result*=i; printf("该数的阶乘为:%ld\n",result); } 该函数在参数n比较小的时候运行完全正常,但是随着n变大(如,超过12)就出现

了问题,结果会溢出而变成意料之外的数据,究其原因,是因为任何基本类型的变量都有一定的表示范围。要计算更大参数的阶乘,可以使用数组存放阶乘结果,于是有了下面的程序: /* 数的阶乘(改进版)*/ #include"stdio.h" main() { int n; printf("请输入一个数:"); scanf("%d",&n); jiecheng(n); } int jiecheng(int n) { int m,i,j,c,t,a[1000]; a[0]=1; m=1; for(i=2;i<=n;i++) { for(c=0,j=0;j

} while(c) { a[m++]=c%10; c/=10; } } printf("该数的阶乘为:"); for(j=m-1;j>=0;j--) printf("%d",a[j]); printf("\n"); } 这样一来,就可以计算大数的阶乘了。如有疑问,多谢赐教!

输入正整数n,计算n的阶乘c++实验报告

实验五 一、实验内容 1、掌握3种循环结构:while,do-while,for的区别与联系,以及他们之间相互转换的方法,并能正确使用他们. 2,掌握与循环语句相关的break语句和continue语句的使用方法. 二、实验目的 1、掌握3种循环结构:while,do-while,for的区别与联系,以及他们之间相互转换的方法,并能正确使用他们. 2,掌握与循环语句相关的break语句和continue语句的使用方法. 三、实验步骤 实践教程例题1 1.输入正整数n,计算n的阶乘. 2.实践教程例2 输入若干字符,统计其中数字字符.白字符和其它字符的个数,输入EOF结束. 3、实践教程例3 N个人围坐成一圈,从1开始顺序编号;游戏开始,从第一个人开始由1到m循环报数,报到m的人退出圈外,问最后留下的那个人原来的序号。 4`书2.3 设计程序将输入的百分制成绩转换为五分制输出,90分以上为5分,80~89为4分,70~79为3分,60~69为两分,60分以下为1分。 书2.5 编译打印如下图形 * * * * * * * * * * * * * * * * * * * * * * * * *

4、书2.7 输入n,求1!+2!+3!+…+n!。 四、实验数据及处理结果 实践教程例1 #include using namespace std; int main (){ int n,i; double result=0; cout<<"请输入正整数:"<>n; if(n<1){ cout<<"输入错误!"<

C++与python的大数阶乘

如何用C++和python解决大数阶乘问题 1000!是个很大的数,C++中没有能储存这么多位数精确数的数据类型,那么如何解决这个问题呢?可以用字符数组来解决,把每次相乘的结果作为字符数组储存,再分别对每一个字符进行处理,大于等于10的进行进位。由于字符数组可以有很大的长度,因此可以计算出1000!的精确值。 实际操作中为了方便,把每次相乘的结果到过来存,例如:4!=[4,2,0,0 0 C++程序如下: #include using namespace std; #define N 1000 static int a[N*3]; int main() { int i,j; int len=1; //每次得到的阶乘的长度 int tem,carry; //临时变量,进位 int count=0; //最终结果中1的个数 a[1]=1; for(i=2;i<=N;i++) { carry=0; for(j=1;j<=len;j++) { tem=a[j]*i+carry; a[j]=tem; carry=tem/10; if(j==len&&carry!=0) { len++; } }

} for(i=len;i>=1;i--) { cout<

数据结构大数相乘

课题名称:大数相乘 1.问题描述 计算机的内存有限,而且各个函数类型的范围有限,如果要计算两个更大的乘数,就会超出范围,得到不精确的数,如何得到更精确的数,而又不受计算机内存空间的限制,本程序就可以解决大数相乘的问题。 2.设计思路 这个程序的关键是如何保存大数的各个数字,以及如何处理大数乘法的进位问题。本人是运用栈的思想做的,先定义一个整型的栈,大数传入栈的整型数组中,在乘法运算函数中,先从一个栈中取出一个大数S1的个位上的数字a,再从另一个大数S2取出一个个位数字b, 再将a*b+d(d为进位数)的个位数字压到栈S中,十位上进位的数字先保存到d中,再从S2中取出一个十位数,与a相乘,得到的个位数字再压到栈S中,再从S2中取出一个数字,以此类推,直到S2 中的数字被a乘完,得到一个新的大数S,将该栈保存到A栈中,将S销毁,再从S1中取出大数的十位数字,与S2的各个数字相乘,得到一个新的大数压到S中,将S保存到B中,将B移位处理后,然后与A相加得到另一个大数,以此类推,最终可相加得到想要的结果。这其中还用到了大数相加的原理。

3.数据结构设计 前面提到,要用到栈的操作,这里,由于一个大数的最大长度是一定的,且大数最多执行的操作是插入和删除操作,所以顺序存储结构可以带来更大益处。为了便于大数相加,将大数的各个数字存入到整型数组中。 #define MAXSIZE 100 typedef struct node { int data[MAXSIZE]; int top; }SeqStack,*PSeqStack; 4.功能函数设计 (1)栈初始化函数Init_SeqStack(char *ch) 此函数是将传入的字符处理成0~9的整数存入整型数组中。将*ch-’0’转化为整数存入S->data[i]中,结束标志是*ch不等于’\0’ (2)首尾倒置函数Convert_SeqStack(PSeqStack A) 此函数是将栈中的数值首尾颠倒,比如以前是1234,现在变成4321。只要将传入的A的栈中的元素依次取出压到C中,再返回C栈即可(3)大数相加函数Add(PSeqStack S1,PSeqStack S2) 此函数是处理两个大数相加的功能。将传入的两个大数压到S1和S2中,当S1或S2不为空时,从S1中取出a,从S2中取出b,得到Result=(a+b)%10+d,其中初始时d=0,再判断Result是否大于10,如

采用汇编语言实现阶乘运算

汇编语言程序设计报告 课程设计题目:采用汇编语言实现阶乘运算 学号:10081437 姓名:张子琦 院系:测试与光电工程学院 专业:测控技术与仪器 指导教师:陈振华

采用汇编语言实现阶乘运算 学生姓名:张子琦班级:10081437 指导老师:陈振华 摘要:汇编语言是微型计算机原理及应用的基础,微机主机和接口所要实现的功能都要通过汇编语言来实现。尽管汇编语言程序设计编程效率低,但其运行效率高、速度快。因此掌握汇编语言是学好微机原理和接口设计的第一步。编写计算N!的程序。数值由键盘输入,结果在屏幕上输出。[1] 关键字:汇编语言N!键盘输入屏幕输出 指导老师签名:

Factorial implemented in assembly language Student name :Ziqi Zhang Class:10081437 Supervisor:Zhenhua Chen Abstract:Assembly language is the basis of the principles and applications of the microcomputer, the microcomputer host functions and interfaces to achieve should be achieved through the assembly language. Despite the low efficiency of assembly language programming programming, but it’s high operating efficiency, and speed. Therefore, the assembly language is the first step to learn Microcomputer Principle and Interface Design. Written calculation of N! Procedures. Numerical keyboard input, output results on the screen. Key words:Assembly language N! Keyboard input Screen output Signature of Supervisor:

阶乘排列组合公式计算

阶乘排列组合公式计算 加法原理:做一件事,完成它可以有N类加法,在第一类办法中有M1种不同的方法,在第二类办法中有M2种不同的方法,……,在第N类办法中有MN种不同的方法。那么完成这件事共有N=M1+M2+...+MN 种不同的方法。即一次性完成的用加法原理。 乘法原理:做一件事,完成它需要分成N个步骤,做第一步有M1种不同的方法,做第二步有M2种不同的方法,……,做第N步有MN种不同的方法,那么完成这件事共有 N=M1×M2×... ×MN 种不同的方法。即二次以上完成的用乘法原理。 排列:从N个不同元素中,任取M(M<=N)个元素,按照一定的顺序排成一列,叫做从N个不同元素中取出M个元素的一个排列。 排列数:从N个不同元素中取出M(M<=N)个元素的所有排列的个数,叫做从N个不同元素中取出M个元素的排列数。记作:Pmn 排列数公式:Pmn =n(n-1)(n-2)...(n-m+1) 全排列:N个不同元素全部取出的一个排列,叫做N个不同元素的一个全排列。 自然数1到N的连乘积,叫做N的阶乘。记作:n! 。0!=1。 全排列公式:Pnn =n! 排列数公式还可写成:Pmn = n!/(n-m)! 组合:从N个不同元素中,任取M(M<=N)个元素并成一组,叫做从N个不同元素中取出M个元素的一个组合。 排列与元素的顺序有关,组合与元素的顺序无关。 组合数:从N个不同元素中取出M(M<=N)个元素的所有组合的个数,叫做从N个不同元素中取出M个元素的组合数。记作:Cmn 组合数公式:Cmn = Pmn / Pmm = n(n-1)(n-2)...(n-m+1)/m! = n!/m!/(n-m)! 组合性质1:Cmn = Cn-mn ( C0n =1) 组合性质2:Cmn+1 = Cmn + Cm-1n

大数乘法

大数乘法 (一)介绍: 还是模拟的方法,用数组c[] 记录a[] 和b[]的乘积。之后在把c[] 中 的每一位变成个位数就ok 了! (二)代码如下: #include #include using namespace std; char a[100],b[100]; int len_a,len_b; int c[200]; void mul(char a[],char b[],int c[],int l_a,int l_b) { int i,j; for(i=l_a-1;i>=0;i--) { for(j=l_b-1;j>=0;j--) c[i+j+2]+=(a[i]-'0')*(b[j]-'0');//这个操作比较好,保证了相乘之后相加形 //成了错位,易于进行c[]每一位的相加操作} for(i=l_a+l_b;i>0;i--) { c[i-1]+=c[i]/10; c[i]%=10; } bool flag= true; i=0; while(c[i]==0) i++; for(;i<=len_a+len_b;i++) { flag=false; cout<

int main() { cin>>a>>b; len_a=strlen(a),len_b=strlen(b); memset(c,0,sizeof(c)); mul(a,b,c,len_a,len_b); return 0; }

大数的阶乘(n!)

信息科学与工程学院 编程设计实验文档 题目:较大数的阶乘 一、设计目的: 1.解决一般大数的阶乘问题,可以避免一般算法实行时的数据溢 出的弊端 2.培养自己对算法的理解,提高自身的水平 3.熟练对c语言的操作,加强对c语言的理解 二、设计分析:

实现一般较小的数的阶乘,可以直接利用普通的乘法进行循环 运算即可,即利用s=n*(n-1)的核心算法。但是,当n比较 大的时候,会造成运算的结果,即s会变得特别大,便会造成 数据溢出。此时,就需要另一种算法,是结果可以保存,不溢 出。那么,这个算法就是要解决这个问题,所以,我想到另一 方式用来解决这个问题,即利用数组。 如下: 首先,定义两个整型的数组: int a[200];//暂且先设定是200位,我称之为“结果数组” int add[200];//我称之为“进位数组” 现在具体说明两个数组的作用: 1.a[200] 比如说,一个数5的阶乘是120,那么我就用这个数组存储它: a[0]=0 a[1]=2 a[2]=1 因此,用这样的数组我们可以放阶乘后是200位的数 2.在介绍add[200]之前,我介绍一下算法的思想,就以6!为 例:

从上面我们知道了5!是怎样存储的。 就在5!的基础上来计算6!,演示如下: fac[0]=fac[0]*6=0 fac[1]=fac[1]*6=12 fac[2]=fac[2]*6=6 3.现在就用到了我们的:“进位数组”add[1000]. 先得说明一下:add[i]就是在第2步中用算出的结果中,第 i位向第i+1位的进位数值。还是接上例: add[0]=0; add[1]=1; // 计算过程:就是 (a[1]+add[0]) % 10=1 add[2]=0; // 计算过程:就是 (a[2]+add[1]) % 10=0 ....... ....... ....... add[i+1] =( a[i+1] + add[i] ) % 10 三、算法流程图

VB程序设计-多种方法求阶乘

VB程序设计-多种方法求阶乘 (作者:草原飞狼 2014年5月26日) 声明:仅供学习与交流使用,高手请飘过,谢谢! 布局 运行界面(1)

运行界面(2) 源代码如下: Private Sub Command1_Click() Rem 求任意数阶乘,不大于171 Dim mul As Double Dim i As Integer Dim k As Integer mul = 1 '赋初值 k = Val(InputBox("请输入一个正整数,不大于171!", "输入提示", "5")) Rem 以下算法是求指定数的阶乘,典型的算法 For i = 1 To k mul = mul * i Next i Print k & "的阶乘结果是:"; mul End Sub Private Sub Command2_Click() Rem 清空 Form1.Cls End Sub Private Sub Command3_Click() Rem 退出 Unload Me End Sub Private Sub Command4_Click()

Rem 普通过程求阶乘 Dim mul As Double Dim i As Integer Dim k As Integer mul = 1 '赋初值 k = Val(InputBox("请输入一个正整数,不大于171!", "输入提示", "5")) Rem 以下算法是求指定数的阶乘 Call fac(k) '函数调用,注意调用方法 Print k & "的阶乘结果是:"; fac(k) End Sub Private Function fac(ByVal k As Integer) As Double 'byval表示参数按值传递Rem 普通的函数过程 Dim i As Integer Dim mul As Double mul = 1 For i = 1 To k mul = mul * i Next i fac = mul '结果返回给函数,典型的用法End Function Private Sub Command5_Click() Rem 递归过程求阶乘 Dim i As Integer Dim k As Integer Dim mul As Double mul = 1 '赋初值 k = Val(InputBox("请输入一个正整数,不大于171!", "输入提示", "5")) Rem 以下递归函数的调用 Call fac_digui(k) Print k & "的阶乘结果是:"; fac_digui(k) End Sub Private Function fac_digui(ByVal k As Integer) As Double Rem 递归过程求阶 Rem 以下是递归算法求阶乘,注意写法,编写递归算法时,方法类似 If k = 1 Then fac_digui = 1 Else fac_digui = fac_digui(k - 1) * k End If End Function

数据结构之大数阶乘

实习一之大数阶乘 // dashujiecheng.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #include using namespace std; //链表的类定义 class ChainNode { friend class Chain; private: int data; ChainNode* link; }; class Chain { public: Chain(){first = 0;} ~Chain(); bool IsEmpty() const {return first == 0;} int Length() const; bool Find(int k, int& x)const; int Search(const int& x) const; Chain& Delete(int k, int& x);

Chain& Insert(int k, const int& x); Chain& Change(int k, int x); void OutputOne(const ChainNode* current); void Output(); int OutOfBounds(); private: ChainNode* first; }; //删除链表中的所有节点 Chain::~Chain() { ChainNode * next; while(first) { next = first->link; delete first; first = next; } } //确定链表的长度 int Chain::Length() const { ChainNode* current = first; int len = 0; while(current) { len++; current = current->link;

经验技巧6-2 大数阶乘优化算法

经验技巧6-2 大数阶乘优化算法 【例6-6】给出了大数阶乘的算法,该算法使用数组存放阶乘的结果,每一个数组元素存放结果的一位。计算十万的阶乘需要近260秒的时间,实际上只要程序中的N足够大,还可以求更大数的阶乘,但程序执行的时间会更长,可能要几个小时,甚至更长,因此需要考虑对算法进行优化。 int型数组的每一个元素可以存放的最大整数为2147483647,是一个十位数,而算法中每一个元素只存放结果的一位,显然太浪费了。 由于算法中需要计算自然数n与数组元素值的乘积加上前一位的进位,所以每个数组元素的位数不能太多,否则将超过最大整数2147483647而导致溢出,如果每个数组元素存放4位数,大约可计算到二十万的阶乘,确保结果是精确的,如果再使用无符号基本整型,大约可计算到四十万的阶乘,确保结果是精确的。 由此,定义符号常量M的值为10000作为模数,符号常量B的值为4表示数组元素存放的最多位数,符号常量N的值为600000表示n!结果位数的B分之一,存放n!结果的数组bit定义为静态无符号基本整型。 计算i!时将原来的用10除处理进位和余数改为用M除。 由于除存放最高位的元素外,每个元素都存放B位,而存放最高位的元素可能不足B位,输出前需先统计存放最高位元素bit[k]的位数,另外,低位的0(只能输出一个0)和不足B位的应使用B个输出域宽,不足的用0补足,才能保证其它各位均输出B位。 其它说明详见程序代码中的注释。 优化的程序代码: (1)#include "stdio.h" (2)#define M 10000//M与n的乘积不能超过4294967295 (3)#define B 4//数组元素存放的最多位数 (4)#define N 600000 //n!的位数,要足够大 (5)int fact(int bit[],int n) (6){ (7)int i,j,k=N-1,carry;//k表示第一个非0元素的下标 (8)bit[k]=1; (9)for(i=2;i<=n;i++) (10){ (11)carry=0;//carry表示进位数,开始进位数为0 (12)for(j=N-1;j>=k;j--) (13){

相关文档
最新文档