其他分享
首页 > 其他分享> > 对阶乘的另类运算方式

对阶乘的另类运算方式

作者:互联网

在开始之前,我们先列出每一种运算所需的时间复杂度

我们推出对阶乘的含义:

n!=1 * 2 * 3 * 4 *...n

然后经过如下变形:

1 *2 * 3 * 4 * 5..n=2 * 4 * 6 * 8 * 10 *...2n/2^n,

即:

(2n)!/[(1 * 3 * 5...(2n-1]* 2^n )=n!

令2n=t,有:

t!= (t/2)! * (1 * 3 * 5...t-1 * t)*2^(t/2)

over

当然,以上代码可以经过迭代,但最后的复杂度可能高于原阶乘

代码实现:
c语言:

int test(int n) {
	int i,d=1;
	switch (n){
	case 1:
		return 1;
	case 2:
		return 2;
	case 3:
		return 6;
	}
	for (i = 1; i < n - 1; i+=2) {
		d *= i;
	}
	if (n & 1) {
		return d;
	}
	else {
		return test(n / 2) * d* 2<<(n/2);
	}
}

而对于“是否有必要”,我做了个可供测试的子函数(太快了,测不到)

点击查看代码
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#include <string.h>

int main() {
	long long i = NULL, j = NULL, k = NULL;
	long long  int n = 500, d = 1;
	double  add_i, add_j, add_k, end_i, end_j, end_k;
	add_i = clock();
	i=test_1(n);
	end_i = clock();
	add_j = clock();
	j = test_2(n);
	end_j = clock();
	add_k=clock();
	while (--n)
		d *= n;
	end_k=clock();
	k =d ;
	printf(" i %21d,%f j %21d,%f k %21d,%f", i,add_i-end_i,j, add_j - end_j,k, add_k - end_k);
	return 0;
}



int test_1(int n) {
	int i, d = 1;
	switch (n) {
	case 1:
		return 1;
	case 2:
		return 2;
	case 3:
		return 6;
	}
	for (i = 1; i < n - 1; i += 2) {
		d *= i;
	}
	if (n & 1) {
		return d;
	}
	else {
		return test_1(n / 2) * d * 2 << (n / 2);
	}
}


int test_2(int n) {
	int i, d = 1, m = n / 2, t=1;
	switch (n) {
	case 1:
		return 1;
	case 2:
		return 2;
	case 3:
		return 6;
	}
	while (--m)t *= m;
	for (i = 1; i < n - 1; i += 2) {
		d *= i;
	}
	return d * 2 << (n / 2) * t;
}

发现这样的阶乘好像也没有多快..和我之前想的不一样

标签:end,运算,int,另类,test,add,阶乘,return,include
来源: https://www.cnblogs.com/miaomiaomiaomiao/p/15707397.html