C++ 快讀
- 前言
- 輸入的優化
-
- 最簡單的輸入
- 優化1
- 優化2
- 優化3
- 優化4
- 快讀的Bug
前言
衆所周知,C++是有讀入的(廢話) 但是一些特别毒瘤的題目會卡輸入輸出,那麼,我們應該怎麼優化呢?請看這篇文章
輸入的優化
最簡單的輸入
C++有一個輸入方法就是cin,示例:
int x;
cin>>x;
簡單,但是有些慢~~~~
優化1
使用頭檔案
中的
scanf
來完成輸入
例子:
int x;
scanf("%d",&x);
優化2
還是有點慢!我們就要出快讀了!
代碼:
inline int read()
{
int w=1,s=0;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') w=-1;
ch=getchar();
}
while(isdigit(ch))
{
s=s*10+(ch-'0');
ch=getchar();
}
return w*s;
}
可以這樣做的原因是因為輸入單個字元比輸入整數快得多。
為啥?我也不知道為啥
這裡的函數
是判斷一個字元是不是數字。
第一個while循環判斷的是正負數,第二個while循環判斷的是他符号後的值。
優化3
其實這個優化可以說是大佬們的自我安慰。
位運算比普通運算快一點點!
————一名大佬
許多大佬都說位運算快一點,但是真有這樣的嗎?
我不知道
代碼:
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
重點是第十行:x=(x<<1)+(x<<3)+(ch^48);
" << x" 操作為二進制操作,原理是将原二進制數向左平移 x 位,右邊原位置以 0 補齊
例如:
原二進制數 10001 經過 << 2 後,變為 1000100
其效果:
x << 1 == x * 2;
x << 2 == x * 2 * 2;
x << 3 == x * 2 * 2 * 2;
是以 (x<<1)+(x<<3) 可視為 x*10;
後面的 (ch^48) 效果為 ch - = ‘0’;
優化4
終極優化!
代碼:
namespace io{
const int SIZE=1e7+10;
char inbuff[SIZE];
char *l,*r;
inline void init()
{
l=inbuff;
r=inbuff+fread(inbuff,1,SIZE,stdin);
}
inline char gc(){
if(l==r) init();
return (l!=r) ? *(l++):EOF;
}
void read(int &x){
x=0;
char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);c=gc()) x=x*10+c-'0';
}
};
using io::read;
using io::gc;
原理就是一次性把緩沖區的資料全部讀入進來,然後再慢慢配置設定給變量。
等價于
就是讀入整數 x
快讀的Bug
快讀雖好,但有Bug,就是無法讀入一些帶有其他字元(如:空格)的資料。
如:
3
Sqrt(7)
Sqrt(98)
Sqrt(89)
但是scanf可以讀入:
for(int i=1;i<=n;i++)
{
int x;
scanf("Sqrt(%d)",&x);
}
好了,快讀我就講完了,用與不用,您來判定吧~~~