Test Message

[模板] 輸入優化

模板

readChar()

#define BUFSIZ 1048576

inline char readChar()
{
static char buffer[BUFSIZ], * now = buffer + BUFSIZ, * end = buffer + BUFSIZ;
if (now == end)
{
if (end < buffer + BUFSIZ)
return EOF;
end = (buffer + fread(buffer, 1, BUFSIZ, stdin));
now = buffer;
}
return *now++;
}

readInt()

inline char readInt(register int* dst)
{
register char ch;
while ((ch = readChar()) < '-')
if (ch == EOF) return 0;
if (ch == '-')
{
*dst = readChar() ^ '0';
while ((ch = readChar()) >= '0')
* dst = (*dst << 3) + (*dst << 1) + (ch ^ '0');
*dst = ~*dst + 1;
}
else
{
*dst = ch ^ '0';
while ((ch = readChar()) >= '0')
* dst = (*dst << 3) + (*dst << 1) + (ch ^ '0');
}
return 1;
}

readUInt()

inline char readUInt(register unsigned int* dst)
{
register char ch;
while ((ch = readChar()) < '0')
if (ch == EOF) return 0;
*dst = ch ^ '0';
while ((ch = readChar()) >= '0')
* dst = (*dst << 3) + (*dst << 1) + (ch ^ '0');
return 1;
}

readLongLong()

inline char readLongLong(register long long* dst)
{
register char ch;
while ((ch = readChar()) < '-')
if (ch == EOF) return 0;
if (ch == '-')
{
*dst = readChar() ^ '0';
while ((ch = readChar()) >= '0')
* dst = (*dst << 3) + (*dst << 1) + (ch ^ '0');
*dst = ~*dst + 1;
}
else
{
*dst = ch ^ '0';
while ((ch = readChar()) >= '0')
* dst = (*dst << 3) + (*dst << 1) + (ch ^ '0');
}
return 1;
}

readULongLong()

inline char readULongLong(register unsigned long long* dst)
{
register char ch;
while ((ch = readChar()) < '0')
if (ch == EOF) return 0;
*dst = ch ^ '0';
while ((ch = readChar()) >= '0')
* dst = (*dst << 3) + (*dst << 1) + (ch ^ '0');
return 1;
}

readDouble()

inline int readDouble(register double* dst)
{
register char ch, nag;
while (((ch = readChar()) < '-'))
if (ch == EOF) return 0;
if (ch == '-')
nag = 1, *dst = readChar() ^ '0';
else
nag = 0, *dst = ch ^ '0';
while ((ch = readChar()) >= '0')
* dst = *dst * 10 + (ch ^ '0');
if (ch == '.')
{
register double m = 1;
while ((ch = readChar()) >= '0')
* dst += (ch ^ '0') * (m *= 0.1);
}
if (nag)* dst = -*dst;
return 1;
}

概述

本組模板為輸入優化模板,使用此模板取代 scanf() 可以大幅減少從資料流取得數組的時間,本組模板所有函式皆需要透過 readChar() 完成,請在使用時一併引入。

參數

BUFSIZ

此巨集用來定義緩衝區大小。

dst

本參數用來接收格式化後的數值。

返回值

若讀取到字元 -1 (EOF) 回傳 0,否則回傳 1。

實例

#include <stdio.h>
#define BUFSIZ 1048576

inline char readChar()
{
static char buffer[BUFSIZ], * now = buffer + BUFSIZ, * end = buffer + BUFSIZ;
if (now == end)
{
if (end < buffer + BUFSIZ)
return EOF;
end = buffer + fread(buffer, 1, BUFSIZ, stdin);
now = buffer;
}
return *now++;
}

inline char readInt(register int* dst)
{
register char ch;
while ((ch = readChar()) < '-')
if (ch == EOF) return 0;
if (ch == '-')
{
*dst = readChar() ^ '0';
while ((ch = readChar()) >= '0')
* dst = (*dst << 3) + (*dst << 1) + (ch ^ '0');
*dst = ~*dst + 1;
}
else
{
*dst = ch ^ '0';
while ((ch = readChar()) >= '0')
* dst = (*dst << 3) + (*dst << 1) + (ch ^ '0');
}
return 1;
}

int main()
{
int val;
while (readInt(&val))
{
printf("%d\n", val);
}
return 0;
}

注意事項

  • 在 32 位元架構下的編譯器,由於不需要做右移處理所以 int 的速度一般會比 short 來的更快 (或至少一樣快),所以在記憶體空間足夠的請況下,保持使用 int 是比較好的選擇。

  • 為了加快速度,過濾字元時使用 (ch < '0' (有號為'-'))、判斷數字使用 (ch >= '0') 作為字元判斷依據如果字串中包含不符合條件的字元請自行修改判斷式或採用以下嚴格判斷的方式避免錯誤。

    有號

    (((ch = readChar()) < '0' || ch > '9') && ch != '-')

    無號

    ((ch = readChar()) < '0' || ch > '9')

    判斷數字

    ((ch = readChar()) >= '0' && ch <= '9')

  • 如果情況允許,使用整數型態模擬浮點運算,因為整數型態運算速度遠高於浮點,且不會有失真問題。

更新紀錄

2019-9-6
  • 傳入參數改為 register