用getchar()和putchar()加速IO(含整型快速IO和浮点型快速IO)
概述:使用getchar()和putchar(),以及cmath头文件中的一些函数,基本实现了以下函数
scanf(“%u”,&x)
scanf(“%d”,&x)
scanf(“%lf”,&x)
printf(“%u”,x)
printf(“%d”,x)
printf(“%f”,x)
printf(“%*f”,precision,x)
若有不完善的地方,欢迎指正。
完整代码:
[cpp] view plaincopy

- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
- const double dten[10] = {0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8, 1e-9};
- ///一般题目至多要求输出小数点后6位,此数组足矣。
- char outputbuf[15]; /// 声明成全局变量可以减小开销
- /*
- 读非负整数
- 返回值:若成功读到一个整数返回true,若读到EOF返回false
- */
- inline bool unsigned_input(int& x)
- {
- char c;
- while (!isdigit(c = getchar()))
- if (c == EOF) return false;
- x = 0;
- while (isdigit(c))
- {
- x = x * 10 + (c & 15);
- c = getchar();
- }
- return true;
- }
- /*
- 读整数
- 注意-0的输出为0
- 返回值:若成功读到一个整数返回true,若读到EOF返回false
- */
- inline bool input(int& x)
- {
- char c;
- while ((c = getchar()) != ‘-‘ && !isdigit(c))
- if (c == EOF) return false;
- bool neg = false;
- if (c == ‘-‘)
- x = 0, neg = true;
- else
- x = c & 15;
- while (isdigit(c = getchar()))
- x = x * 10 + (c & 15);
- if (neg) x = -x;
- return true;
- }
- /*
- 读正负浮点、零(也可以读整数)
- 注意无法判断”.14″这样的输入
- 注意-0.00这样的输入使得x=-0.000000
- 返回值:none
- */
- inline void input(double& x)
- {
- char c;
- while ((c = getchar()) != ‘-‘ && !isdigit(c))
- ;
- bool neg = false;
- if (c == ‘-‘)
- x = 0, neg = true;
- else
- x = c & 15;
- while (isdigit(c = getchar()))
- x = x * 10 + (c & 15);
- if (c == ‘.’)
- {
- double ten = 1.0;
- while (isdigit(c = getchar()))
- x += (c & 15) * (ten /= 10);
- }
- if (neg) x = -x;
- }
- /*
- 读正负浮点、零(也可以读整数)
- 并且可以判断”.14″这样的输入
- 注意-0.00这样的输入使得x=-0.000000
- 返回值:none
- */
- inline void special_input(double& x)
- {
- char c;
- while ((c = getchar()) != ‘-‘ && c != ‘.’ && !isdigit(c))
- ;
- bool neg = false;
- if (c == ‘-‘)
- {
- neg = true;
- c = getchar();
- }
- x = 0;
- if (c != ‘.’)
- {
- // 整数部分
- x = c & 15;
- while (isdigit(c = getchar()))
- x = x * 10 + (c & 15);
- }
- if (c == ‘.’)
- {
- // 小数部分
- double ten = 1.0;
- while (isdigit(c = getchar()))
- x += (c & 15) * (ten /= 10);
- }
- if (neg) x = -x;
- }
- /*
- 输出非负整数
- 返回值:none
- */
- inline void unsigned_output(int x)
- {
- if (x == 0)
- putchar(‘0’);
- else
- {
- int p = 0;
- while (x)
- {
- outputbuf[p++] = x % 10;
- x /= 10;
- }
- for (int i = p – 1; i >= 0; i–)
- putchar(‘0’ + outputbuf[i]); // 逆序输出
- }
- }
- /*
- 输出整数
- 返回值:none
- */
- inline void output(int x)
- {
- if (x == 0)
- putchar(‘0’);
- else
- {
- if (x < 0)
- {
- x = -x;
- putchar(‘-‘);
- }
- int p = 0;
- while (x)
- {
- outputbuf[p++] = x % 10;
- x /= 10;
- }
- for (int i = p – 1; i >= 0; i–)
- putchar(‘0’ + outputbuf[i]); // 逆序输出
- }
- }
- /*
- 输出精度为precision的浮点数(四舍五入),对-0.0输出0.000000
- 如果precision为0,则只输出离x最近的整数
- 返回值:none
- */
- inline void output(int precision, double x)
- {
- if (x < 0)
- {
- x = -x;
- putchar(‘-‘);
- }
- if (precision)
- {
- // 整数部分
- double intpart;
- x = modf(x, &intpart); // from <math.h>
- unsigned_output((int)intpart);
- //小数部分
- putchar(‘.’);
- for (int i = 1; i < precision && x < dten[i]; ++i)
- putchar(‘0’);// 输出小数点后有多少0
- int ten = 1;
- while (precision–)
- ten *= 10;
- unsigned_output((int)round(x * ten));
- }
- else
- unsigned_output((int)round(x));
- }
- /*
- 输出精度为precision的浮点数(四舍五入),对-0.0输出-0.000000
- 如果precision为0,则只输出离x最近的整数
- 返回值:none
- */
- inline void exact_output(int precision, double x)
- {
- if (signbit(x)) // from <math.h>, return true if the sign of x is negative(就相当于返回x的符号位)
- {
- x = -x;
- putchar(‘-‘);
- }
- if (precision)
- {
- // 整数部分
- double intpart;
- x = modf(x, &intpart); // from <math.h>
- unsigned_output((int)intpart);
- //小数部分
- putchar(‘.’);
- for (int i = 1; i < precision && x < dten[i]; ++i)
- putchar(‘0’);// 输出小数点后有多少0
- int ten = 1;
- while (precision–)
- ten *= 10;
- unsigned_output((int)round(x * ten));
- }
- else
- unsigned_output((int)round(x));
- }
- /*
- 输出精度为6的浮点数(四舍五入),对-0.0输出0.000000
- 返回值:none
- */
- inline void output(double x)
- {
- output(6, x);
- }
- /*
- 输出精度为6的浮点数(四舍五入),并且对-0.0输出-0.000000
- 注意:按IEEE 754标准,-0.0和0.0在输出上是有区别的,但是二者实际上是相等的
- 返回值:none
- */
- inline void exact_output(double x)
- {
- exact_output(6, x);
- }
- int main(void)
- {
- int t;
- double x;
- unsigned_input(t);
- while (t–)
- {
- input(x);
- output(x);
- putchar(10);
- exact_output(x);// same as printf(“%f”,x);
- putchar(10);
- }
- return 0;
- }