【问题标题】:Fast input for long and long long in C?在C语言中快速输入long和long long?
【发布时间】:2014-04-07 03:35:27
【问题描述】:

所以我一直在使用这个函数来解决 codechef 问题已经有一段时间了,现在作为整数的快速输入方法。

我的问题是这实际上是如何工作的,什么是 fgetc_unlocked(stdin)(尽管它已被注释),最重要的是我如何优化它以长期运行。

代码如下:

inline void Scan_f(int a)
{
char c = 0;
while(c<33)//shouldn't value of c to compare be less than 9 as digit vary between 0 to 9?? 
//c = fgetc_unlocked(stdin);
c = getc(stdin);
a = 0;
while(c>33)
{
a = a*10 + c - '0';
//c = fgetc_unlocked(stdin);
c = getc(stdin);
}

【问题讨论】:

  • 为什么是 c&gt;33 而不是 while(c&gt;' ')?为什么char c = 0int c = 0
  • @chux 谢谢 .. 这解释了其中一个问题。我在代码中编辑了注释,以便对普通读者更有意义。其他问题呢?
  • fgetc_unlockedgetc 的线程不安全版本。如果您的程序保证是单线程的,这可能会提供一些性能优势。
  • @AndrewMedico '1' 实际上是 0x31。 33(十进制)是“!” while() 基本上跳过了前导 ASCII 控制和 ' ' 字符。整个事情甚至都没有尝试验证输入字符是否在0..9 范围内,只是盲目地假设这一点。
  • 糟糕,失败。这就是我没有花几秒钟仔细检查 ASCII 表的结果。

标签: c input long-integer long-long large-data


【解决方案1】:

在我看来,代码应该是:

inline unsigned long long Scan_f()
{
    int c;
    do
        c = fgetc(stdin);
    while ( (c < '0' || c > '9') && c != EOF );

    unsigned long long a = 0;
    while ( c >= '0' && c <= '9' )
    {
        a = a*10 + (c - '0');
        c = fgetc(stdin);
    }
    return a;
}

在您发布的代码中,a 是一个按值传递的参数,因此不清楚调用函数将如何得知您对a 的更改。

fgetc_unlocked 函数应该是fgetc 的更快版本。这是一个 GNU 扩展。

a 成为有符号类型没有意义,因为您的解析永远无法检索到负值。

此版本不检查溢出;如果您想处理这种可能性,那么您需要在执行a = a*10 之前添加检查。

不用担心c &lt; '0' 等部分的效率,编译器已经为您生成最佳代码。他们可以很好地处理这样的简单情况。当然,它可以比从输入流中读取字符的速度更快地检查它;输入流速度将成为瓶颈。

【讨论】:

    猜你喜欢
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 2010-11-30
    相关资源
    最近更新 更多