C++的快读与快写

1. 基于 getchar/putchar 的快读快写(最常用)

  • 整数快读(支持负数)
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 * 10 + (ch - '0');
        ch = getchar();
    }
    return x * f;
}
  • 无符号整数快读(更快)
inline unsigned int read() {
    unsigned int x = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9') ch = getchar();
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + (ch - '0');
        ch = getchar();
    }
    return x;
}
  • 整数快写(支持负数)
inline void write(int x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

2. 基于缓冲区优化的快读(更快)

  • 使用静态缓冲区的快读
char buf[1 << 21], *p1 = buf, *p2 = buf;
inline char getc() {
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
inline int read() {
    int x = 0, f = 1;
    char ch = getc();
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getc();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + (ch - '0');
        ch = getc();
    }
    return x * f;
}
  • 使用缓冲区的快写
char pbuf[1 << 21], *pp = pbuf;
inline void push(const char &c) {
    if (pp - pbuf == (1 << 21)) {
        fwrite(pbuf, 1, (1 << 21), stdout);
        pp = pbuf;
    }
    *pp++ = c;
}
inline void write(int x) {
    static int sta[35];
    int top = 0;
    if (x < 0) {
        push('-');
        x = -x;
    }
    do {
        sta[top++] = x % 10;
        x /= 10;
    } while (x);
    while (top) push(sta[--top] + '0');
    push('\n'); // 可以根据需要修改
}

// 程序结束时调用 flush() 确保所有输出被写入
inline void flush() {
    fwrite(pbuf, 1, pp - pbuf, stdout);
    pp = pbuf;
}

3. 针对不同数据类型的优化实现

  • 读取长整型
inline long long readll() {
    long long 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 * 10 + (ch - '0');
        ch = getchar();
    }
    return x * f;
}
  • 读取字符串(一行)
inline void readstr(char *str) {
    char ch = getchar();
    while (ch == ' ' || ch == '\n') ch = getchar();
    while (ch != ' ' && ch != '\n' && ch != EOF) {
        *str++ = ch;
        ch = getchar();
    }
    *str = '\0';
}

4. 终极优化版本(竞赛常用)

namespace FastIO {
    const int SZ = 1 << 20;
    char inbuf[SZ], outbuf[SZ];
    int in_left = 0, in_right = 0;
    int out_right = 0;
    
    inline void load() {
        int len = fread(inbuf, 1, SZ, stdin);
        in_left = 0;
        in_right = len;
    }
    
    inline char getchar() {
        if (in_left >= in_right) load();
        if (in_left >= in_right) return EOF;
        return inbuf[in_left++];
    }
    
    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 * 10 + (ch - '0');
            ch = getchar();
        }
        return x * f;
    }
    
    inline void flush() {
        fwrite(outbuf, 1, out_right, stdout);
        out_right = 0;
    }
    
    inline void putchar(char ch) {
        outbuf[out_right++] = ch;
        if (out_right == SZ) flush();
    }
    
    inline void write(int x) {
        if (x < 0) {
            putchar('-');
            x = -x;
        }
        if (x > 9) write(x / 10);
        putchar(x % 10 + '0');
    }
    
    struct Flusher {
        ~Flusher() { flush(); }
    } flusher;
}

using FastIO::read;
using FastIO::write;
using FastIO::putchar;
  • 使用示例
int main() {
    int n = read();  // 读取一个整数
    write(n);        // 输出一个整数
    putchar('\n');   // 输出换行
    
    // 使用命名空间版本
    int m = FastIO::read();
    FastIO::write(m);
    FastIO::putchar('\n');
    
    return 0;
    // FastIO::Flusher 会在程序结束时自动调用 flush()
}

性能比较

  1. 基础版 (getchar/putchar):比 scanf/printf 快约 2-3 倍

  2. 缓冲区版 (fread/fwrite):比基础版快约 2-3 倍

  3. 终极优化版:比缓冲区版再快约 1.5 倍

在大多数算法竞赛中,基础版或缓冲区版已经足够使用。终极优化版更适合输入数据量特别大的极端情况。

### C++ 中实现取输入的方法 在处理大规模数据时,C++ 的标准输入方法 `cin` 可能会成为性能瓶颈。为了提升效率,可以采用以下几种优化技术: #### 1. 解除 `cin` 和 `cout` 的绑定 默认情况下,`cin` 和 `cout` 是同步的,即每次执行 `cin` 操作时都会刷新 `cout` 缓冲区。这会影响性能,尤其是在频繁交互的情况下。可以通过调用 `std::ios::sync_with_stdio(false)` 来解除这种绑定关系[^4]。 ```cpp #include <iostream> int main() { std::ios::sync_with_stdio(false); // 关闭同步 int a, b; std::cin >> a >> b; std::cout << (a + b); return 0; } ``` #### 2. 禁用 `cin` 自动刷新 `cout` 除了关闭同步外,还可以通过设置 `cin.tie(NULL)` 进一步减少不必要的开销。这种方法能够防止每次 `cin` 调用时都自动刷新 `cout` 缓存。 ```cpp #include <iostream> int main() { std::ios::sync_with_stdio(false); std::cin.tie(NULL); // 禁止 cin 刷新 cout int a, b; std::cin >> a >> b; std::cout << (a + b); return 0; } ``` #### 3. 使用 C 风格的 I/O 函数 相比 C++ 的流式输入输出 (`cin`, `cout`),C 风格的函数如 `scanf` 和 `printf` 更加高效。它们直接操作底层缓冲区而不涉及额外的类型检查和格式化逻辑[^2]。 ```cpp #include <cstdio> int main() { int a, b; scanf("%d %d", &a, &b); // 使用 scanf 提升速度 printf("%d\n", a + b); // 使用 printf 输出结果 return 0; } ``` #### 4. 实现自定义模板 对于更高需求的情况,可以编自己的取函数来进一步加速输入过程。这种方式绕过了标准库中的复杂机制并专注于核心功能[^3]。 ```cpp inline void fast_read(int &x) { char ch = getchar(); bool neg = false; x = 0; while (!isdigit(ch)) { if (ch == '-') neg = true; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch ^ '0'); ch = getchar(); } if (neg) x = -x; } int main() { int a, b; fast_read(a); fast_read(b); printf("%d\n", a + b); return 0; } ``` 以上四种方法都可以有效改善 C++ 程序中输入部分的时间消耗问题。具体选择哪种取决于实际应用场景以及个人偏好。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值