【发布时间】:2014-12-28 02:46:18
【问题描述】:
我的问题不是关于算法,而是关于 C 编程语言的一些令人困惑的问题。 我遇到了如下问题:
问题描述
N! (N 阶乘)对于较大的 N 值可能非常烦人且难以计算。因此,我不想计算 N!,而是想知道其中有多少位。 (记住 N!= N * (N - 1) * (N - 2) * ... * 2 * 1)
输入
输入的每一行都有一个整数 N 0
输出
对于 N 的每个值,打印出 N! 中有多少位数。
我的代码是这样的:
#include<stdio.h>
int main()
{
int n ;
while(scanf("%d",&n)&&n!=EOF)//1
//while(scanf("%d",&n)!=EOF)//2
{
int result=1;
int i;
double temp = 1;
for(i=n;i>0;i--)
{
temp*=i;
while((temp/10)>1)
{
result++;
temp=temp/10;
}
}
printf("%d\n",result);
}
return 0;
}
当我使用while(scanf("%d",&n) && n!=EOF)时,我使用的在线法官显示Time Limit Exceeded,当我将其更改为while(scanf("%d",&n)!=EOF)时,一切顺利。我认为n!=EOF可能需要太多时间,所以什么是EOF的本质?
【问题讨论】:
-
EOF 定义为 -1 I.E. 0xFFFFFFFF 对于 32 位系统。但是,对 scanf 函数的调用存在几个问题:1) 代码应始终检查 scanf 的返回值以确保输入/转换成功 2) scanf 的返回值永远不会被 EOF,它会为 0 或更大。
-
位数的计数很尴尬,而且位置不正确。只需要对 N! 的最终值执行“位数计数”。没有10!很快就超过了“int”持有的能力。建议使用“long long int”(64 位)(或者可能是“bignum”函数)。
-
@user3629249 1)
EOF未定义为-1。它肯定总是一个负的int常数。 2)scanf("%d",&n)的可能返回值为0、1或EOF。 -
注意:使用
for(i=n;i>0;i--) { temp *= i; while(temp >= 1.0e31) { result += 31; temp /= 1.0e31; } } while(temp >= 10.0) { result++; temp /= 10.0;} printf("%d\n",result);之类的代码可以运行得更快(更准确)。 31 被选为DBL_MAX至少是1.0e31 * 1,000,000。