Skip to content

Instantly share code, notes, and snippets.

@longbuilder
Last active August 29, 2015 14:09
Show Gist options
  • Save longbuilder/5580c4908f4efe137948 to your computer and use it in GitHub Desktop.
Save longbuilder/5580c4908f4efe137948 to your computer and use it in GitHub Desktop.
fast io
#ifndef FAST_IN_H_
#define FAST_IN_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define INPUT_BLOCK_SIZE 4096 * 512
class FastInput
{
public:
FastInput() : block_size_(INPUT_BLOCK_SIZE),
low_watermark_(100),rbegin_(NULL), rend_(NULL), is_eof_(false)
{
buffer_ = (char *)malloc(block_size_);
}
~FastInput()
{
free(buffer_);
}
template <typename T>
inline void getInteger(T &num); // 获取一个有符号的整数
inline void getLetter(char &c); // 读取一个字母,[a-zA-Z]
private:
inline void readFromStdin();
private:
const size_t block_size_;
size_t low_watermark_; // buffer中数据长度小于此值开始从底层读入。 public的成员函数一次读出的数据类型长度不能超过这个值。
char *buffer_;
char *rbegin_;
char *rend_;
bool is_eof_;
};
void FastInput::readFromStdin()
{
size_t nbytes_remain = rend_ - rbegin_;
if (nbytes_remain > low_watermark_ || is_eof_) return;
if (nbytes_remain > 0) memmove(buffer_, rbegin_, nbytes_remain);
size_t nread = fread(buffer_ + nbytes_remain, 1, block_size_ - nbytes_remain, stdin);
if (0 == nread)
{
is_eof_ = true;
rbegin_ = buffer_;
rend_ = rbegin_ + nbytes_remain;
}
else
{
rbegin_ = buffer_;
rend_ = rbegin_ + nbytes_remain + nread;
}
}
template <typename T>
void FastInput::getInteger(T &num)
{
readFromStdin();
bool negative = false;
char ch,sign = '\0';
while (rbegin_ < rend_)
{
ch = *rbegin_;
if (ch < '0' || ch > '9')
{
sign = ch;
++rbegin_;
}
else
break;
}
if (sign == '-') negative = true;
num = 0;
while (rbegin_ < rend_)
{
ch = *rbegin_;
if (ch < '0' || ch > '9')
{
break;
}
else
{
num = ch - '0' + 10 * num;
++rbegin_;
}
}
num = negative ? 0-num : num;
}
void FastInput::getLetter(char &ch)
{
readFromStdin();
while (rbegin_ < rend_)
{
ch = *rbegin_;
++rbegin_;
if ((ch >= 'A' && ch <= 'Z') ||
(ch >= 'a' && ch <= 'z'))
{
return;
}
}
}
#endif
#ifndef FAST_OUT_H_
#define FAST_OUT_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define OUTPUT_BLOCK_SIZE 4096 * 512
class FastOutput
{
public:
FastOutput() : block_size_(OUTPUT_BLOCK_SIZE),
flush_watermark_(OUTPUT_BLOCK_SIZE - 100),rbegin_(NULL), rend_(NULL)
{
buffer_ = (char *)malloc(block_size_);
rbegin_ = rend_ = buffer_;
}
~FastOutput()
{
flush();
free(buffer_);
}
inline void addInt(int e);
inline void addChar(char c);
inline void flush(); // 写完后需要强制flush
private:
inline void tryFlush();
private:
const size_t block_size_;
size_t flush_watermark_; // buffer中数据长度大于此值开始往底层写
char *buffer_;
char *rbegin_;
char *rend_;
};
void FastOutput::tryFlush()
{
if (rend_ - rbegin_ > flush_watermark_)
flush();
}
void FastOutput::addInt(int e)
{
tryFlush();
int ret = sprintf(rend_, "%d", e);
rend_ += ret;
}
void FastOutput::addChar(char c)
{
tryFlush();
*rend_ = c;
++rend_;
}
void FastOutput::flush()
{
size_t size = rend_ - rbegin_;
if (size > 0)
{
fwrite(rbegin_, size, 1, stdout);
rend_ = rbegin_;
}
}
#endif
#include "fast_in.h"
#include "fast_out.h"
int main(int argc, char *argv[])
{
const int n = 5;
int *a = new int[n];
FastInput in;
for (int i = 0; i < n; ++i)
{
in.getInt(a[i]);
}
FastOutput out;
for (int i = 0; i < n; ++i)
{
out.addInt(a[i]);
out.addChar(' ');
}
out.addChar('\n');
out.flush();
delete []a;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment