我的问题不是关于算法,而是关于C编程语言的混乱。 我遇到了如下问题:
问题描述
N! (N阶乘)可能非常刺激并且难以计算N的大值。因此,我想知道其中有多少位数,而不是计算N !. (记住N!= N *(N - 1)*(N - 2)* ... * 2 * 1)
输入
输入的每一行将在其上具有单个整数N <0。 N&lt; 100万(100万)输入由文件结束终止。
输出
对于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
的本质是什么?
答案 0 :(得分:6)
这不是两句话的时间,是他们有不同的含义
下一个将scanf读取的值与EOF进行比较,这是一个错误,如果到达文件末尾,scanf将不会加载n中的任何值:
while(scanf("%d",&n) && n!=EOF)
这是检测文件结尾的正确方法:
while(scanf("%d",&n)!=EOF)
通常EOF == -1,因为判断中的输入不包含-1,程序无限循环。
正如评论中所述,检查scanf所做的转换次数通常会更好,因为它会检查输入是否有效(*)。鉴于您在格式字符串中询问了1次转换(&#34;%d&#34;),您可以检查scanf是否返回1:
while(scanf("%d", &n) == 1)
(*)如果你必须遵循一个严格的格式(例如,如果要求这个数字必须跟在exaclty之后,它可能无法验证某些情况),那么使用strtol进行转换会更好,检查strtol消耗完整的一行。
由于这个特殊问题来自使用在线评判的编程竞赛,因此输入结构良好,通常不需要进行此类测试。
答案 1 :(得分:3)
两种情况都不适合使用(但使用scanf("%d", &n) != EOF
的情况更好)。
循环应写为:
while (scanf("%d",&n) == 1)
因为您要求scanf
转换1个值,而scanf
的返回值是成功转换的项目数。
答案 2 :(得分:0)
I would strongly suggest using the following code rather than
the illmannered scanf() function:
#include<stdio.h>
int main()
{
unsigned int n ; // user input after conversion
long long int result=0; // maybe use uint64_t
char inArray[100] = {'\0'}; // user input array
int i; // loop counter
int digitCount = 0; // number of digits to display factorial value
printf("\nwhen enter a number\n");
printf(" then pgm will output factorial for that number\n");
printf(" then number of digits in factorial value\n");
printf("\n\nPlease enter first number: (or <ctrl-z> to exit)");
while( NULL != fgets( inArray, sizeof(inArray), stdin )
{
n = (unsigned)atoi( inArray );
if( 0 == n ) {result = 0;}
else if( 1 == n ) {result = 1;}
else if( 2 == n ) {result = 2;}
else
{
result = n;
for(i=(n-1);i>1;i--)
{
result *= i;
} // end calculate factorial
} // end if
printf("factorial value: %lld\n",result);
// setup work area usage
memset( inArray, 0x00, sizeof(inArray) );
sprintf( inArray, "%lld", result );
// calculate and display number of digits
digitCount = strlen(inArray);
printf("digit count: %d\n", digitCount );
// clear work area and prompt for next input from user
memset( inArray, 0x00, sizeof(inArray) );
printf("\n\nPlease enter next number: (or <ctrl-z> to exit)");
} // end while
return 0;
} // end function: main