天天看點

C++ 快讀前言輸入的優化快讀的Bug

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);
}
           

好了,快讀我就講完了,用與不用,您來判定吧~~~