也就是輸入輸出外掛
明明在C語言中有scanf()、printf(),C++中有cin、cout,為什么我們還要用輸入輸出外掛呢?
這個問題很明顯,一定是因為這些輸入輸出函數功能過于強大而導致效率低,(很多時候,功能越強大的東西越臃腫),而我們使用的輸入輸出外掛既然叫外掛,那說明其一定有很大的優勢,而這方面優勢就體現在術有專攻上。原來的輸入輸出函數因為要應對不同類型的輸入輸出,所以內部一定做了很多的判斷,而我們在遇見實際問題時,往往都是對特定類型的進行輸入輸出,所以這些判斷就顯得無用且浪費資源。這時,我們的輸入輸出外掛也就有了存在的必要性,也就應運而生。
我們都知道,scanf()、printf()、cin、cout其實就是對其他一些基礎的獲取或輸出語句(getchar() putchar()等)進行封裝,而這些基礎的函數功能弱,效率高,所以我們的輸入輸出外掛也是仿照著scanf()、printf()、cin、cout來實現的,只不過做了針對性的改造,最終我們改造出來多種功能比scanf()等弱、比getchar()等強,效率比scanf()等高、比gerchar()等低的函數,從而達到針對性的作用,減少了不必要的資源消耗。
當然輸入輸出外掛一般用在大量輸入輸出的情況下,這樣性價比才高一些,否則得不償失(犧牲了代碼長度而換來了微不足道的效率提升)。
---------------------?
適用于正整數
template <class T>
inline void scan_d(T &ret)?
{char c;?ret = 0;while ((c = getchar()) < '0' || c > '9');while (c >= '0' && c <= '9'){?ret = ret * 10 + (c - '0'), c = getchar();}
}
適用于正負整數
template <class T>
inline bool scan_d(T &ret)?
{char c;?int sgn;if (c = getchar(), c == EOF)?{return 0; //EOF?}while (c != '-' && (c < '0' || c > '9'))?{c = getchar();?}sgn = (c == '-') ? -1 : 1;ret = (c == '-') ? 0 : (c - '0');?while (c = getchar(), c >= '0' && c <= '9')?{ret = ret * 10 + (c - '0');?}ret *= sgn;return 1;
}template <class T>
inline void print_d(T x)?
{?if (x > 9)?{print_d(x / 10);?}putchar(x % 10 + '0');
}
僅適合純數字輸入輸出
int Scan()
{ ? // ?輸入外掛 ?int res = 0, flag = 0; ?char ch; ?if ((ch = getchar()) == '-')?{ ??flag = 1; ?} ? ?else if(ch >= '0' && ch <= '9')?{res = ch - '0';?}while ((ch = getchar()) >= '0' && ch <= '9') ?{res = res * 10 + (ch - '0'); ?}return flag ? -res : res; ?
} ?void Out(int a)?
{ ? // ?輸出外掛 ?if (a < 0)?{putchar('-');a = -a;} ?if (a >= 10){Out(a / 10); ?}putchar(a % 10 + '0'); ?
} ?int main()?
{ ?int T, n; ?scanf ("%d", &T); ?while (T--)?{ ?n = Scan(); ?Out(n); ?printf("\n"); ?} ?return 0; ?
}
適用于正負數(int,long long,float,double)
template <class T>
bool scan_d(T &ret)
{char c;?int sgn;?T bit = 0.1;if (c=getchar(), c==EOF)?{return 0;}while (c! = '-' && c != '.' && (c < '0' || c > '9'))?{c = getchar();}sgn = (c == '-') ? -1 : 1;ret = (c == '-') ? 0 : (c - '0');while (c = getchar(), c >= '0' && c <= '9'){ret = ret * 10 + (c - '0');}if (c == ' ' || c == '\n'){ret *= sgn;return 1;}while (c = getchar(), c >= '0' && c <= '9'){ret += (c - '0') * bit, bit /= 10;}ret *= sgn;return 1;
}template <class T>
inline void print_d(int x)
{if (x > 9){print_d(x / 10);}putchar(x % 10 + '0');
}
套裝
char buf[MAXIN], *ps = buf, *pe = buf + 1;inline void rnext()
{if (++ps == pe){pe = (ps = buf) + fread(buf, sizeof(char), sizeof(buf) / sizeof(char), stdin);}return ;
}template <class T>
inline bool in(T &ans)
{ans = 0;T f = 1;if (ps == pe){return false;}do{rnext();if ('-' == *ps){f = -1;}} while (!isdigit(*ps) && ps != pe);if (ps == pe){return false;}do{ans = (ans << 1) + (ans << 3) + *ps - 48;rnext();} while (isdigit(*ps) && ps != pe);ans *= f;return true;
}char bufout[MAXOUT], outtmp[50], *pout = bufout, *pend = bufout + MAXOUT;inline void write()
{fwrite(bufout, sizeof(char), pout - bufout, stdout);pout = bufout;return ;
}inline void out_char(char c)
{*(pout++) = c;if (pout == pend){write();}return ;
}inline void out_str(char *s)
{while (*s){*(pout++) = *(s++);if (pout == pend){write();}}return ;
}template <class T>
inline void out_int(T x)
{if (!x){out_char('0');return ;}if (x < 0){x = -x, out_char('-');}int len = 0;while (x){outtmp[len++] = x % 10 + 48;x /= 10;}outtmp[len] = 0;for (int i = 0, j = len - 1; i < j; i++, j--){swap(outtmp[i], outtmp[j]);}out_str(outtmp);return ;
}
其他
上面那個輸入正負整數的有點難用。?
再附一個:
void in(int &m)
{char ch;int flag = 0;while ((ch = getchar()) < '0' || ch > '9'){if (ch == '-'){flag = 1;}}for (m = 0; ch >= '0' && ch <= '9'; ch = getchar()){m = m * 10 + ch - '0';}if (flag){m *= -1;}
}
?
struct FastIO
{static const int S = 100 << 1;int wpos;char wbuf[S];FastIO() : wpos(0) {}inline int xchar(){static char buf[S];static int len = 0, pos = 0;if (pos == len){pos = 0;len = (int)fread(buf, 1, S, stdin);}if (pos == len){return -1;}return buf[pos++];}inline int xint(){int s = 1, c = xchar(), x = 0;while (c <= 32){c = xchar();}if (c == '-'){s = -1;c = xchar();}for (; '0' <= c && c <= '9'; c = xchar()){x = x * 10 + c - '0';}return x * s;}~FastIO(){if (wpos){fwrite(wbuf, 1, wpos, stdout);wpos = 0;}}
} io;
添加 FastIOstrtok和sscanf結合輸入
/** ?空格作為分隔輸入,讀取一行的整數*/
gets(buf);int v;
char *p = strtok(but, " ");?
while (p)
{sscanf(p, "%d", &v);p = strtok(NULL," ");?
}
1. 一般輸入輸出掛
template <typename T> ?
inline bool scan_d (T &ret) { ?char c; ?int sgn; ?if (c = getchar(), c == EOF) return 0; //EOF ?while (c != '-' && (c < '0' || c > '9') ) {if((c = getchar()) == EOF) return 0;}sgn = (c == '-') ? -1 : 1; ?ret = (c == '-') ? 0 : (c - '0'); ?while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0'); ?ret *= sgn; ?return 1; ?
} ?
template<typename T>
void print(T x) {static char s[33], *s1; s1 = s;if (!x) *s1++ = '0';if (x < 0) putchar('-'), x = -x;while(x) *s1++ = (x % 10 + '0'), x /= 10;while(s1-- != s) putchar(*s1);
}
template<typename T>
void println(T x) {print(x); putchar('\n');
}
2. 加強版輸入輸出掛
原理是將數據一次性全部讀入到內存中。
namespace IO {const int MT = 10 * 1024 * 1024; ?/// 10MB 請注意輸入數據的大小!!!char IO_BUF[MT];int IO_PTR, IO_SZ;/// 要記得把這一行添加到main函數第一行!!!void begin() {IO_PTR = 0;IO_SZ = fread (IO_BUF, 1, MT, stdin);}template<typename T>inline bool scan_d (T & t) {while (IO_PTR < IO_SZ && IO_BUF[IO_PTR] != '-' && (IO_BUF[IO_PTR] < '0' || IO_BUF[IO_PTR] > '9'))IO_PTR ++;if (IO_PTR >= IO_SZ) return false;bool sgn = false;if (IO_BUF[IO_PTR] == '-') sgn = true, IO_PTR ++;for (t = 0; IO_PTR < IO_SZ && '0' <= IO_BUF[IO_PTR] && IO_BUF[IO_PTR] <= '9'; IO_PTR ++)t = t * 10 + IO_BUF[IO_PTR] - '0';if (sgn) t = -t;return true;}inline bool scan_s (char s[]) {while (IO_PTR < IO_SZ && (IO_BUF[IO_PTR] == ' ' || IO_BUF[IO_PTR] == '\n') ) IO_PTR ++;if (IO_PTR >= IO_SZ) return false;int len = 0;while (IO_PTR < IO_SZ && IO_BUF[IO_PTR] != ' ' && IO_BUF[IO_PTR] != '\n')s[len ++] = IO_BUF[IO_PTR], IO_PTR ++;s[len] = '\0';return true;}template<typename T>void print(T x) {static char s[33], *s1; s1 = s;if (!x) *s1++ = '0';if (x < 0) putchar('-'), x = -x;while(x) *s1++ = (x % 10 + '0'), x /= 10;while(s1-- != s) putchar(*s1);}template<typename T>void println(T x) {print(x); putchar('\n');}
};
?
總結
以上是生活随笔為你收集整理的快速输入输出函数的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。