zoukankan      html  css  js  c++  java
  • C++读入神器——文操快读(oj也可以用)

    当某天,本蒟蒻沉迷于卡常的时候:

    图

    我……

    突然,YYKdalao说:用文操快读啊!

    然后

    图2

    喔~目瞪口呆

    不多说,上源码:

    本来用的读入方式:

    inline void Read( int &x ) {
    	x = 0; char ch = getchar();
    	for( ; ch < '0' || ch > '9'; ch = getchar() );
    	for( ; ch >= '0' && ch <= '9'; ch = getchar() )
    		x = x * 10 + ch - '0';
    	return;
    }
    

    文操快读:

    const int MAX_SIZE = 1 << 15;
    char *l, *r, buf[ MAX_SIZE ];
    inline int gc() {
    	if( l == r )
    		if( l == ( r = ( l = buf ) + fread( buf, 1, MAX_SIZE, stdin ) ) ) return -1;
    	return *l++; 
    }
    inline void Read( int &x ) {
    	char c = gc();
    	for(; c < 48 || c > 57; c = gc() );
    	for( x = 0; c > 47 && c < 58; c = gc() )
    		x = ( x << 3 ) + ( x << 1 ) + ( c ^ 48 );
    	return;
    }
    

    以下为2019.11.04 update
    实际上,输出也同样可以使用 fwrite 加速。并且 fwrite 可以直接输出到屏幕上。(这与 fread 需要重定向stdin,或者用命令行里的< 不同。)更为方便的是,可以使用 sprintf 或者 vsnprintf 来方便地将一些内容写入字符数组中。下面贴上模板:

    说明:你可以像 printf 和 scanf 一样使用里面的 Printf 和 Scanf 函数。但是 Scanf 函数的实现有些愚蠢(只能用%d表示一个int,并且不能有其他东西)。所以如果没有特殊需求的话最好用 Read 读取单个整数。你也可以自己写适合的 Read 函数。 输出流最后不一定需要 FlushOutput ,因为在销毁结构体的时候会执行这一步(这并不意味着你不需要fclose)。你可以通过更改 MAX_OUTPUT_ONCE 的值来更改 Printf 函数单次最大输出量。(如果超过了也许仍然能够正确输出,但那样会有一些不必要的错误。)
    v0.1.0 之后提供了真正像scanf那样的读入方法。你可以用三句话实现(但是这仅仅是方便读入,并没有加速这个过程(fread带来的优化被memcpy抵消了QwQ)):

    IO.Ready(); //预留足够的空间(至少为 MAX_INPUT_ONCE,不过你也需要保证一次读入的长度不超过 MAX_INPUT_ONCE)
    sscanf(IO.It(), "...%n", ..., &IO.C); //读入
    IO.Forward(); //刷新流,不然下一次读入会读重复的内容
    

    注意: 结构体创建之后,就会从输入流中预读入。默认输入输出流是 stdin 和 stdout。所以不使用 FastIO 的时候请不要进行声明。

    /*====================    Header : FastIO    ====================*/
    /*====================     version 0.1.1     ====================*/
    /*==================== Programed By chy-2003 ====================*/
    /*
     * Logs : 
     * version 0.1.1 : Fix bugs when flush input buffers
     * version 0.1.0 : Add new ways to read
     *     new    function char *It();
     *     new    function void Ready();
     *     new    function void Forward();
     *     You can read any thing like : but to make sure read less than MAX_INPUT_ONCE charactors once.
     *         IO.Ready(); 
     *         sscanf(IO.It(), "...%n", ..., &IO.C); 
     *         IO.Forward();
     * version 0.0.1 : Update
     *     change function int GetChar();    : private -> public
     *     new    function int UnGetC();     : public (unget the last char. Return value 0:success; -1:fail)
     *     change function void Read(int &); : rewrite with UnGetC. will run UnGetC() after reading an integer
     * version 0.0.0 : Creat
     *     function 'Read' and 'Scanf' will return the number of values get successfully.
     *     function 'Read' : 
     *         int Read(int&);
     *     funtion 'Scanf' : 
     *         Warning : This funtion works in a stupid way
     *         int Scanf(const char *, ...);
     *         supports : all(just like printf);
     *
     *     funtion 'Printf' : 
     *         Warning : Output may be cut off if the length longer than ((1 << 9) - 1), or you can set MAX_OUTPUT_ONCE equals to MAX_OUTPUT_BUFFER_SIZE
     *         void Printf(const char *, ...);
     *         supports : all(just like printf)
     */
    
    #ifndef _MY_FASTIO_
    #define _MY_FASTIO_
    
    #include <cstdio>
    #include <cstring>
    #include <stdarg.h>
    
    #define MAX_INPUT_BUFFER_SIZE (1 << 15)
    #define MAX_OUTPUT_BUFFER_SIZE (1 << 15)
    #define MAX_INPUT_ONCE (1 << 9)
    #define MAX_OUTPUT_ONCE (1 << 9)
    //notice : I check the buffer BEFORE every option.
    //notice : please make sure MAX_INPUT_BUFFER_SIZE > 2 * MAX_INPUT_ONCE
    
    struct FastIO {
    //private:
        char *InputBufferLeft, *InputBufferRight, InputBuffer[MAX_INPUT_BUFFER_SIZE + 1];//The last position is for ''
        char OutputBuffer[MAX_OUTPUT_BUFFER_SIZE + 1]; // The last position is for ''
        int OutputBufferUsed;
        FILE *InputStream, *OutputStream;
        char cTemp;
        short iTemp;
        bool CanGet;
    
        inline void ClearInputBuffer();
        inline int GetFromInputStream();
        inline void SetInputBufferToLeft();
        inline bool EndOfFile();
    
    public:
        int C;
        //Basic
        FastIO(FILE *_InputStream = stdin, FILE *_OutputStream = stdout);
        ~FastIO();
    
        //Input
        inline int GetChar();
        inline int UnGetC();
        inline int Read(int &x);
        inline int Scanf(const char *Format, ...);
        inline void Ready();
        inline void Forward();
        inline char *It();
    
        //Output
        inline void FlushOutput();
        inline void Printf(const char *Format, ...);
    };
    
    FastIO::FastIO(FILE *_InputStream, FILE *_OutputStream) :
        InputStream(_InputStream), OutputStream(_OutputStream),
        InputBufferLeft(InputBuffer), InputBufferRight(InputBuffer), OutputBufferUsed(0) {
            InputBuffer[MAX_INPUT_BUFFER_SIZE] = OutputBuffer[MAX_OUTPUT_BUFFER_SIZE] = '';
            CanGet = true;
            GetFromInputStream();
            return;
        }
    
    FastIO::~FastIO() {
        FlushOutput();
        return;
    }
    
    inline void FastIO::ClearInputBuffer() {
        InputBufferLeft = InputBufferRight = InputBuffer;
        return;
    }
    
    inline int FastIO::GetFromInputStream() {
        if (!CanGet) return 1;
        char *Last = InputBufferRight;
        InputBufferRight = InputBufferRight + fread(InputBufferRight, 1, InputBuffer + MAX_INPUT_BUFFER_SIZE - InputBufferRight, InputStream);
        if (InputBufferRight == Last) CanGet = false;
        return !CanGet;
    }
    
    inline void FastIO::SetInputBufferToLeft() {
        memcpy(InputBuffer, InputBufferLeft, InputBufferRight - InputBufferLeft);
        InputBufferRight = InputBuffer + (InputBufferRight- InputBufferLeft);
        InputBufferLeft = InputBuffer;
        return;
    }
    
    inline int FastIO::GetChar() {
        if (InputBufferLeft == InputBufferRight) {
            ClearInputBuffer();
            if (GetFromInputStream()) return -1;
        }
        return *InputBufferLeft++;
    }
    
    inline int FastIO::Read(int &x) {
        cTemp = GetChar();
        iTemp = 1;
        for(; cTemp < 48 || cTemp > 57; cTemp = GetChar())
            if (cTemp == -1)
                return 0;
            else
                if (cTemp == '-')
                    iTemp = -1;
        for(x = 0; cTemp > 47 && cTemp < 58; cTemp = GetChar())
            x = (x << 3) + (x << 1) + (cTemp ^ 48);
        UnGetC();
        x *= iTemp;
        return 1;
    }
    
    inline int FastIO::Scanf(const char *Format, ...) {
        int CountRead, Len, i, j;
        CountRead = 0;
        Len = strlen(Format);
        va_list ap;
        va_start(ap, Format);
        for (i = 0, j; i < Len; i = j + 1) {
            j = i;
            while (j + 1 < Len && Format[j + 1] != '%') ++j;
            if (j - i == 1 && Format[j] == 'd') {
                int *x;
                x = va_arg(ap, int *);
                Read(*x);
                ++CountRead;
            }
        }
        va_end(ap);
        return CountRead;
    }
    
    inline void FastIO::Ready() {
        if (InputBufferRight - InputBufferLeft < MAX_INPUT_ONCE && CanGet && (InputBufferRight - InputBuffer == MAX_INPUT_BUFFER_SIZE)) {
            SetInputBufferToLeft();
            GetFromInputStream();
        }
        return;
    }
    
    inline char *FastIO::It() {
        return InputBufferLeft;
    }
    
    inline void FastIO::Forward() {
        InputBufferLeft = InputBufferLeft + C;
        return;
    }
    
    inline void FastIO::FlushOutput() {
        if (OutputBufferUsed)
            fwrite(OutputBuffer, 1, OutputBufferUsed, OutputStream);
        OutputBufferUsed = 0;
        return;
    }
    
    inline void FastIO::Printf(const char *Format, ...) {
        if (OutputBufferUsed >= MAX_OUTPUT_BUFFER_SIZE - MAX_OUTPUT_ONCE)
            FlushOutput();
        va_list ap;
        va_start(ap, Format);
        OutputBufferUsed += vsnprintf(OutputBuffer + OutputBufferUsed, MAX_OUTPUT_BUFFER_SIZE - OutputBufferUsed, Format, ap);
        va_end(ap);
        return;
    }
    
    inline int FastIO::UnGetC() {
        if (InputBuffer != InputBufferLeft) {
            --InputBufferLeft;
            return 0;
        }
        return -1;
    }
    
    #undef MAX_INPUT_BUFFER_SIZE
    #undef MAX_OUTPUT_BUFFER_SIZE
    #undef MAX_INPUT_ONCE
    #undef MAX_OUTPUT_ONCE
    
    #endif
    
    
    /*==================== End of Header : FastIO ====================*/
    
  • 相关阅读:
    JAX-RS:@PathVariable @RequestParam @ModelAttribute等参数绑定注解详解
    关于重定向RedirectAttributes的用法
    数据库事务的四大特性以及事务的隔离级别
    电脑打开任务管理器出现卡顿
    IDEA: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value
    git学习命令
    python 输入 与如何查看文档 小结
    python formatters 与字符串 小结 (python 2)
    Hibernate 配置文件与实体类
    python编码问题 与 代码换行问题
  • 原文地址:https://www.cnblogs.com/chy-2003/p/9916869.html
Copyright © 2011-2022 走看看