阶乘(factorial)是基斯顿·卡曼(Christian Kramp, 1760 – 1826)于1808年发明的运算符号。阶乘,也是数学里的一种术语。
任何大于1的自然数n阶乘表示方法:
n!=1×2×3×……×n
或
n!=n×(n-1)!
n的双阶乘:
当n为奇数时表示不大于n的所有奇数的乘积
如:7!!=1×3×5×7
当n为偶数时表示不大于n的所有偶数的乘积(除0外)
如:8!!=2×4×6×8
小于0的整数-n的阶乘表示:
(-n)!= 1 / (n+1)!
0!=1,注意(0的阶乘是存在的)
我们所说的阶乘是定义在自然数范围里的(大多科学计算器只能计算0~69的阶乘),小数没有阶乘,像0.5!,0.65!,0.777!都是错误的。
自然数就是我们常说的正整数和0。整数包括自然数
import java.util.Date;
public class Oldsl {
/**
* @param args
*/
public static void main(String[] args) {
long s=System.currentTimeMillis();
Oldsl.js(12);
long d=System.currentTimeMillis();
System.out.println(d-s);
// System.out.println(Oldsl.Jc(12));
// System.out.println(Oldsl.js(12));
}
public static int Jc(int n){
if(n<0){
return 0;
}
if(n<2&&n>=0){
return 1;
}
int result = 1;
if(n>=2){
for(int i=1;i<=n;i++){
result*=i;
}
}
return result;
}
public static int js(int n){
if(n<0){
return 0;
}
if(n<2&&n>=0){
return 1;
}
int result = 1;
if(n>=2){
result=n*js(n-1);
}
return result;
}
}
递归和循环性能分析:
public static void main(String[] args) {
int n=20;
long s=System.currentTimeMillis();
for(int i=1;i<5000000;i++){
Oldsl.Jc(n);
}
long d=System.currentTimeMillis();
System.out.println("循环时间"+(d-s));
long s1=System.currentTimeMillis();
for(int i=1;i<5000000;i++){
Oldsl.js(n);
}
long d1=System.currentTimeMillis();
System.out.println("递归时间:"+(d1-s1));
}
循环时间516
递归时间:1265
从计算结果可以看出,当计算量小的时候看不出来。随的计算量得增大,循环的性能要比递归高的多,所以尽量用循环,不用用递归。
如果该一下方法,用BigInteger来计算,看一下性能问题:
public static BigInteger Jc(int n){
BigInteger result = BigInteger.ONE;
if(n>=2){
for(int i=1;i<=n;i++){
BigInteger temp=new BigInteger(i+"");
result=result.multiply(temp);
}
}
return result;
}
long s1=System.currentTimeMillis();
for(int i=1;i<5000000;i++){
Oldsl.Jc(20);
}
long d1=System.currentTimeMillis();
System.out.println("时间:"+(d1-s1));
时间:44453
同样的循环次数,耗时就相当多,所以BigInteger性能不是很好
任何大于1的自然数n阶乘表示方法:
n!=1×2×3×……×n
或
n!=n×(n-1)!
n的双阶乘:
当n为奇数时表示不大于n的所有奇数的乘积
如:7!!=1×3×5×7
当n为偶数时表示不大于n的所有偶数的乘积(除0外)
如:8!!=2×4×6×8
小于0的整数-n的阶乘表示:
(-n)!= 1 / (n+1)!
0!=1,注意(0的阶乘是存在的)
我们所说的阶乘是定义在自然数范围里的(大多科学计算器只能计算0~69的阶乘),小数没有阶乘,像0.5!,0.65!,0.777!都是错误的。
自然数就是我们常说的正整数和0。整数包括自然数
import java.util.Date;
public class Oldsl {
/**
* @param args
*/
public static void main(String[] args) {
long s=System.currentTimeMillis();
Oldsl.js(12);
long d=System.currentTimeMillis();
System.out.println(d-s);
// System.out.println(Oldsl.Jc(12));
// System.out.println(Oldsl.js(12));
}
public static int Jc(int n){
if(n<0){
return 0;
}
if(n<2&&n>=0){
return 1;
}
int result = 1;
if(n>=2){
for(int i=1;i<=n;i++){
result*=i;
}
}
return result;
}
public static int js(int n){
if(n<0){
return 0;
}
if(n<2&&n>=0){
return 1;
}
int result = 1;
if(n>=2){
result=n*js(n-1);
}
return result;
}
}
递归和循环性能分析:
public static void main(String[] args) {
int n=20;
long s=System.currentTimeMillis();
for(int i=1;i<5000000;i++){
Oldsl.Jc(n);
}
long d=System.currentTimeMillis();
System.out.println("循环时间"+(d-s));
long s1=System.currentTimeMillis();
for(int i=1;i<5000000;i++){
Oldsl.js(n);
}
long d1=System.currentTimeMillis();
System.out.println("递归时间:"+(d1-s1));
}
循环时间516
递归时间:1265
从计算结果可以看出,当计算量小的时候看不出来。随的计算量得增大,循环的性能要比递归高的多,所以尽量用循环,不用用递归。
如果该一下方法,用BigInteger来计算,看一下性能问题:
public static BigInteger Jc(int n){
BigInteger result = BigInteger.ONE;
if(n>=2){
for(int i=1;i<=n;i++){
BigInteger temp=new BigInteger(i+"");
result=result.multiply(temp);
}
}
return result;
}
long s1=System.currentTimeMillis();
for(int i=1;i<5000000;i++){
Oldsl.Jc(20);
}
long d1=System.currentTimeMillis();
System.out.println("时间:"+(d1-s1));
时间:44453
同样的循环次数,耗时就相当多,所以BigInteger性能不是很好