大家好,欢迎来到IT知识分享网。
前言
在编写代码的时候、做信息题目的时候,如果输入输出的数据量比较大的话,经常一不小心就TLE(Time Limit Exceeded,即速度超限,时间超时,通俗的来说就是爆时间),这种情况下就需要scanf和printf,但是万一这两个家伙也不够用了咋办?那么就该是我们的快读快写闪亮登场啦!
普通快读
上定义
这可以使得代码更加具有可读性
#define f_Getchar() getchar() #define f_Putchar(ch) putchar(ch)
f_Getchar() 即快速(fast)获取字符
f_Putchar() 即快速输出字符
至于为什么要这样做后面再说
整数输入
int快读
inline void inputI(int* i){ char nagative = 0 ; char ch = '\0' ; (*i) = 0 ; while((ch = f_Getchar()) < 48 || ch > 57)if(ch == '-')nagative = 1 ; while(ch > 47 && ch < 58){ (*i) = ((*i) << 1) + ((*i) << 3) + (ch & 0xCF) ; ch = f_Getchar() ; } if(nagative)(*i) = -(*i) ; return ; }
简单介绍原理:首先获取字符,如果是非数字,则一直获取直到获取到数字,如果有负号则标记。接着获取一段连续的数字字符,转换为数字。
long long快读
inline void inputLL(long long* i){ char nagative = 0 ; char ch = '\0' ; (*i) = 0 ; while((ch = f_Getchar()) < 48 || ch > 57)if(ch == '-')nagative = 1 ; while(ch > 47 && ch < 58){ (*i) = ((*i) << 1) + ((*i) << 3) + (ch & 0xCF) ; ch = f_Getchar() ; } if(nagative)(*i) = -(*i) ; return ; }
原理同上
long long快读(无参数,返回数值)
inline long long inget(){ long long i = 0 ; char nagative = 0 ; char ch = '\0' ; while((ch = f_Getchar()) < 48 || ch > 57)if(ch == '-')nagative = 1 ; while(ch > 47 && ch < 58){ i = (i << 1) + (i << 3) + (ch & 0xCF) ; ch = f_Getchar() ; } if(nagative)i = -i ; return i ; }
原理同上
浮点数输入
float 快读
inline void inputF(float* t){ (*t) = inget() ; float t2 = 0.0F,p = 0.1 ; char ch = f_Getchar() ; while(ch > 47 && ch < 58 && p > 1e-6F){ t2 += (ch ^ '0') * p ; p *= 0.1 ; ch = f_Getchar() ; } *t += t2 ; return ; }
原理:获取两端分开的连续数字字符,前面一段作为整数部分,后面一段作为小数部分。
double 快读
inline void inputD(double* t){ *t = inget() ; double t2 = 0.0,p = 0.1 ; char ch = f_Getchar() ; while(ch > 47 && ch < 58 && p > 1e-13){ t2 += (ch ^ '0') * p ; p *= 0.1 ; ch = f_Getchar() ; } *t += t2 ; return ; }
原理同上
字符串输入
字符串正常输入
inline void inputS(char* s){ char ch = f_Getchar() ; while(ch == ' ' || ch == '\n')ch = f_Getchar() ; while(ch != ' ' && ch != '\n')*s = ch,++ s,ch = f_Getchar() ; *s = '\0' ; return ; }
e……这就不用多说了吧
字符串确定最大长度的输入
inline void inputSs(char* s,unsigned long long len){ char ch = f_Getchar() ; while(ch == ' ' || ch == '\n')ch = f_Getchar() ; while((len --) && (ch != ' ' && ch != '\n'))*s = ch,++ s,ch = f_Getchar() ; *s = '\0' ; return ; }
输入一整行的字符串
inline void inputL(char* s){ char ch = f_Getchar() ; while(ch == '\n')ch = f_Getchar() ; while(ch != '\n')*s = ch,++ s,ch = f_Getchar() ; *s = '\0' ; return ; }
字符输入
字符输入(输入可显示字符)
inline void inputC(char* ch){ (*ch) = f_Getchar() ; while((*ch) == ' ' || (*ch) == '\n')(*ch) = f_Getchar() ; return ; }
获取字符(任意字符均可)
f_Getchar(&ch) ;
普通快写
整数快写
int快写
void outputI(int i){ if(i < 0)f_Putchar('-'),i = -i ; if(i > 9)outputI(i / 10) ; f_Putchar((i % 10) | 0x30) ; return ; }
long long快写
void outputLL(long long i){ if(i < 0)f_Putchar('-'),i = -i ; if(i > 9)outputLL(i / 10) ; f_Putchar((i % 10) | 0x30) ; return ; }
字符串快写
正常字符串快写
inline void outputS(const char* s){ while(*s)f_Putchar(*s ++) ; return ; }
输出一行字符串
inline void outputSL(const char* s){ while(*s && *s != '\n')f_Putchar(*s ++) ; return ; }
浮点数快写
double快写
#define outputD(x) printf("%g",x)
对于输出,printf是我目前发现的最快的方法
double快写(可控小数位数)
inline void outputDl(double x,unsigned char len) { printf("%.*lf",len,x) ; return ; }
float快写
#define outputF(x) printf("%g",x)
float快写(可控小数位数)
inline void outputFl(float x,unsigned char len) { printf("%.*f",len,x) ; return ; }
字符快写
#define outputC(ch) f_Putchar(ch)
超级快读快写
ok,现在也是该揭开悬念了,前面define的定义就是为了下面的内容!!!让我们把前面的定义替换成如下代码:
#ifdef IO_SUPER_FAST #ifndef IO_BUFFER_SIZE #define IO_BUFFER_SIZE (0xfffff) #endif static char i_buffer[IO_BUFFER_SIZE],*f = i_buffer,*b = i_buffer ; char f_Getchar(){ if(f == b){ b = i_buffer + fread(i_buffer,1,IO_BUFFER_SIZE,stdin) ; f = i_buffer ; if(f == b)return EOF ; } return *(f ++) ; } static char o_buffer[IO_BUFFER_SIZE],*t = o_buffer ; void f_Putchar(char x){ if((t - o_buffer) >= IO_BUFFER_SIZE){ fwrite(o_buffer,1,IO_BUFFER_SIZE,stdout) ; t = o_buffer ; } *(t ++) = x ; return ; } void put_buffer(){ fwrite(o_buffer,t - o_buffer,1,stdout) ; t = o_buffer ; return ; } #else #define f_Getchar() getchar() #define f_Putchar(ch) putchar(ch) #define put_buffer() #endif
当当当!!!这就是超级快读快写!
现在让我们一起解读
IO_SUPER_FAST
这是一个宏定义,如果在这段代码之前定义了IO_SUPER_FAST,#ifdef IO_SUPER_FAST判断成立,则会执行下面的两个函数、静态变量定义,即开启了超级快读快写
IO_BUFFER_SIZE
这定义了超级快读快写的缓冲区大小,如果没有定义过则定义为0xfffff,即十进制的1,048,575,这既不会使得程序内存超限,也可以提供一个很快的速度。(一般题目都会给出128MB即以上的内存,而这里只占用了不到一MB的内存,除非是程序压得很死,但是也可以手动更改,在代码前面定义就好了)
i_buffer
这是输入的缓冲区,大小由IO_BUFFER_SIZE决定
f
这是一个指针,指向当前正在使用的到的缓冲区的位置
b
这是一个指针,指向缓冲区内有效数据的结尾
f_Getchar
判断当前是否有有效的数据,如果有则返回,并使f增加一,否则重新读取数据,并重新判断,如若读取数据失败则返回EOF(文件末尾标志)
o_buffer
这是输出的缓冲区,大小由IO_BUFFER_SIZE决定
t
这是一个指针,指向当前输出缓冲区内,有效数据的末尾
f_Putchar
将一个字符输出到输出缓冲区内,如果输出缓冲区已满则将所有数据输出,并清空缓冲区。
put_buffer
将所有缓冲区内所有有效数据输出,并清空缓冲区。(一般放在完成输出时的地方,或者程序的末尾)
全代码
注意:
如果想要开启超级快读快写模式,只要在文件的最前面加上宏定义
#define IO_SUPER_FAST
语句即可。如果觉得还不够快,还可以在文件头部加上:
#define IO_BUFFER_SIZE (0xfffffff)
一定一定要在程序的最后(return 0之前)使用put_buffer()函数!
要不然就会有一些内容不被输出出来!
在控制台输入的时候!输入完一段之后它是不会成功获取内容、并且运行下面的代码输出的!
这不是卡住了!而是需要按下Ctrl+Z键手动结束输入才行!
要不然它就会卡住!直到缓冲区满为止!!!
#include <stdio.h> //#define IO_SUPER_FAST /* 超级快读快写的开关在这!!!! 如果没有注释掉上面那一条语句, 就会开启超级快读快写模式! 如果觉得还不够快,还可以在文件头部加上: #define IO_BUFFER_SIZE (0xfffffff) */ #ifdef IO_SUPER_FAST #ifndef IO_BUFFER_SIZE #define IO_BUFFER_SIZE (0xfffff) #endif static char i_buffer[IO_BUFFER_SIZE],*f = i_buffer,*b = i_buffer ; char f_Getchar(){ if(f == b){ b = i_buffer + fread(i_buffer,1,IO_BUFFER_SIZE,stdin) ; f = i_buffer ; if(f == b)return EOF ; } return *(f ++) ; } static char o_buffer[IO_BUFFER_SIZE],*t = o_buffer ; void f_Putchar(char x){ if((t - o_buffer) >= IO_BUFFER_SIZE){ fwrite(o_buffer,1,IO_BUFFER_SIZE,stdout) ; t = o_buffer ; } *(t ++) = x ; return ; } void put_buffer(){ fwrite(o_buffer,t - o_buffer,1,stdout) ; t = o_buffer ; return ; } #else #define f_Getchar() getchar() #define f_Putchar(ch) putchar(ch) #define put_buffer() #endif inline long long inget(){ long long i = 0 ; char nagative = 0 ; char ch = '\0' ; while((ch = f_Getchar()) < 48 || ch > 57)if(ch == '-')nagative = 1 ; while(ch > 47 && ch < 58){ i = (i << 1) + (i << 3) + (ch & 0xCF) ; ch = f_Getchar() ; } if(nagative)i = -i ; return i ; } inline void inputLL(long long* i){ char nagative = 0 ; char ch = '\0' ; (*i) = 0 ; while((ch = f_Getchar()) < 48 || ch > 57)if(ch == '-')nagative = 1 ; while(ch > 47 && ch < 58){ (*i) = ((*i) << 1) + ((*i) << 3) + (ch & 0xCF) ; ch = f_Getchar() ; } if(nagative)(*i) = -(*i) ; return ; } inline void inputI(int* i){ char nagative = 0 ; char ch = '\0' ; (*i) = 0 ; while((ch = f_Getchar()) < 48 || ch > 57)if(ch == '-')nagative = 1 ; while(ch > 47 && ch < 58){ (*i) = ((*i) << 1) + ((*i) << 3) + (ch & 0xCF) ; ch = f_Getchar() ; } if(nagative)(*i) = -(*i) ; return ; } inline void inputF(float* t){ (*t) = inget() ; float t2 = 0.0F,p = 0.1 ; char ch = f_Getchar() ; while(ch > 47 && ch < 58 && p > 1e-13){ t2 += (ch ^ '0') * p ; p *= 0.1 ; ch = f_Getchar() ; } *t += t2 ; return ; } inline void inputD(double* t){ *t = inget() ; double t2 = 0.0,p = 0.1 ; char ch = f_Getchar() ; while(ch > 47 && ch < 58 && p > 1e-13){ t2 += (ch ^ '0') * p ; p *= 0.1 ; ch = f_Getchar() ; } *t += t2 ; return ; } inline void inputS(char* s){ char ch = f_Getchar() ; while(ch == ' ' || ch == '\n')ch = f_Getchar() ; while(ch != ' ' && ch != '\n')*s = ch,++ s,ch = f_Getchar() ; *s = '\0' ; return ; } inline void inputSs(char* s,unsigned long long len){ char ch = f_Getchar() ; while(ch == ' ' || ch == '\n')ch = f_Getchar() ; while((len --) && (ch != ' ' && ch != '\n'))*s = ch,++ s,ch = f_Getchar() ; *s = '\0' ; return ; } inline void inputL(char* s){ char ch = f_Getchar() ; while(ch == '\n')ch = f_Getchar() ; while(ch != '\n')*s = ch,++ s,ch = f_Getchar() ; *s = '\0' ; return ; } inline void inputC(char* ch){ (*ch) = f_Getchar() ; while((*ch) == ' ' || (*ch) == '\n')(*ch) = f_Getchar() ; return ; } void outputLL(long long i){ if(i < 0)f_Putchar('-'),i = -i ; if(i > 9)outputLL(i / 10) ; f_Putchar((i % 10) | 0x30) ; return ; } void outputI(int i){ if(i < 0)f_Putchar('-'),i = -i ; if(i > 9)outputI(i / 10) ; f_Putchar((i % 10) | 0x30) ; return ; } inline void outputS(const char* s){ while(*s)f_Putchar(*s ++) ; return ; } inline void outputSL(const char* s){ while(*s && *s != '\n')f_Putchar(*s ++) ; return ; } #define outputC(ch) f_Putchar(ch) #define outputD(x) printf("%g",x) inline void outputDl(double x,unsigned char len) { printf("%.*lf",len,x) ; return ; } #define outputF(x) printf("%g",x) inline void outputFl(float x,unsigned char len) { printf("%.*f",len,x) ; return ; }
结尾
全部代码可以封装成一个文件,要用的时候直接include包含即可。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/128471.html