阶乘的算法容易,考虑如下公式:
n! = 1*2*3....*n = 10 ^ [ lg(1) + lg(2) + lg(3) + ... + lg(n) ]
具体方法就是求由1到n的对数和(用10为底的常用对数吧),最后把对数和的整数部分就是最后结果的阶,剩余的小数值求反对数(就是指数)即可.这是懒汉方法,代码10余行,亿阶乘也没有问题.
n! = 1*2*3....*n = 10 ^ [ lg(1) + lg(2) + lg(3) + ... + lg(n) ]
具体方法就是求由1到n的对数和(用10为底的常用对数吧),最后把对数和的整数部分就是最后结果的阶,剩余的小数值求反对数(就是指数)即可.这是懒汉方法,代码10余行,亿阶乘也没有问题.
用那个方法计算的确快,呵呵,C#里结果是“正无穷大”...
这么大的对数和直接求指数肯定会overflow啦!
得到指数和之后不会把它分成整数和小数部分再求么???
{a为序列表,tmp为辅助数组}
procedure merge(var a:listtype; p,q,r:integer);
{将已排序好的子序列a[p..q]与a[q+1..r]合并为有序的tmp[p..r]}
var I,j,t:integer;
tmp:listtype;
begin
t:=p;i:=p;j:=q+1;{t为tmp指针,I,j分别为左右子序列的指针}
while (t< =r) do begin
if (i< =q){左序列有剩余} and ((j >r) or (a[i]< =a[j])) {满足取左边序列当前元素的要求}
then begin
tmp[t]:=a[i]; inc(i);
end
else begin
tmp[t]:=a[j];inc(j);
end;
inc(t);
end;
for i:=p to r do a[i]:=tmp[i];
end;{merge} procedure merge_sort(var a:listtype; p,r: integer); {合并排序a[p..r]}
var q:integer;
begin
if p< >r then begin
q:=(p+r-1) div 2;
merge_sort (a,p,q);
merge_sort (a,q+1,r);
merge (a,p,q,r);
end;
end;
{main}
begin
merge_sort(a,1,n);
end.
“二分法排序”是不是指二分法插入排序?
[email protected]
在已排好序的序列中使用二分法查找插入位置,找到插入位置后和直接插入排序法同样处理。二分法插入排序将关键字比较次数降为nlog2n量级,记录移动次数仍为n2量级。