用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在CODE上查看代码片派生到我的代码片

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <math.h>
  4. const double dten[10] = {0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8, 1e-9};
  5. ///一般题目至多要求输出小数点后6位,此数组足矣。
  6. char outputbuf[15]; /// 声明成全局变量可以减小开销
  7. /*
  8.     读非负整数
  9.     返回值:若成功读到一个整数返回true,若读到EOF返回false
  10. */
  11. inline bool unsigned_input(int& x)
  12. {
  13.     char c;
  14.     while (!isdigit(c = getchar()))
  15.         if (c == EOF) return false;
  16.     x = 0;
  17.     while (isdigit(c))
  18.     {
  19.         x = x * 10 + (c & 15);
  20.         c = getchar();
  21.     }
  22.     return true;
  23. }
  24. /*
  25.     读整数
  26.     注意-0的输出为0
  27.     返回值:若成功读到一个整数返回true,若读到EOF返回false
  28. */
  29. inline bool input(int& x)
  30. {
  31.     char c;
  32.     while ((c = getchar()) != ‘-‘ && !isdigit(c))
  33.         if (c == EOF) return false;
  34.     bool neg = false;
  35.     if (c == ‘-‘)
  36.         x = 0, neg = true;
  37.     else
  38.         x = c & 15;
  39.     while (isdigit(c = getchar()))
  40.         x = x * 10 + (c & 15);
  41.     if (neg) x = -x;
  42.     return true;
  43. }
  44. /*
  45.     读正负浮点、零(也可以读整数)
  46.     注意无法判断”.14″这样的输入
  47.     注意-0.00这样的输入使得x=-0.000000
  48.     返回值:none
  49. */
  50. inline void input(double& x)
  51. {
  52.     char c;
  53.     while ((c = getchar()) != ‘-‘ && !isdigit(c))
  54.         ;
  55.     bool neg = false;
  56.     if (c == ‘-‘)
  57.         x = 0, neg = true;
  58.     else
  59.         x = c & 15;
  60.     while (isdigit(c = getchar()))
  61.         x = x * 10 + (c & 15);
  62.     if (c == ‘.’)
  63.     {
  64.         double ten = 1.0;
  65.         while (isdigit(c = getchar()))
  66.             x += (c & 15) * (ten /= 10);
  67.     }
  68.     if (neg) x = -x;
  69. }
  70. /*
  71.     读正负浮点、零(也可以读整数)
  72.     并且可以判断”.14″这样的输入
  73.     注意-0.00这样的输入使得x=-0.000000
  74.     返回值:none
  75. */
  76. inline void special_input(double& x)
  77. {
  78.     char c;
  79.     while ((c = getchar()) != ‘-‘ && c != ‘.’ && !isdigit(c))
  80.         ;
  81.     bool neg = false;
  82.     if (c == ‘-‘)
  83.     {
  84.         neg = true;
  85.         c = getchar();
  86.     }
  87.     x = 0;
  88.     if (c != ‘.’)
  89.     {
  90.         // 整数部分
  91.         x = c & 15;
  92.         while (isdigit(c = getchar()))
  93.             x = x * 10 + (c & 15);
  94.     }
  95.     if (c == ‘.’)
  96.     {
  97.         // 小数部分
  98.         double ten = 1.0;
  99.         while (isdigit(c = getchar()))
  100.             x += (c & 15) * (ten /= 10);
  101.     }
  102.     if (neg) x = -x;
  103. }
  104. /*
  105.     输出非负整数
  106.     返回值:none
  107. */
  108. inline void unsigned_output(int x)
  109. {
  110.     if (x == 0)
  111.         putchar(‘0’);
  112.     else
  113.     {
  114.         int p = 0;
  115.         while (x)
  116.         {
  117.             outputbuf[p++] = x % 10;
  118.             x /= 10;
  119.         }
  120.         for (int i = p – 1; i >= 0; i–)
  121.             putchar(‘0’ + outputbuf[i]); // 逆序输出
  122.     }
  123. }
  124. /*
  125.     输出整数
  126.     返回值:none
  127. */
  128. inline void output(int x)
  129. {
  130.     if (x == 0)
  131.         putchar(‘0’);
  132.     else
  133.     {
  134.         if (x < 0)
  135.         {
  136.             x = -x;
  137.             putchar(‘-‘);
  138.         }
  139.         int p = 0;
  140.         while (x)
  141.         {
  142.             outputbuf[p++] = x % 10;
  143.             x /= 10;
  144.         }
  145.         for (int i = p – 1; i >= 0; i–)
  146.             putchar(‘0’ + outputbuf[i]); // 逆序输出
  147.     }
  148. }
  149. /*
  150.     输出精度为precision的浮点数(四舍五入),对-0.0输出0.000000
  151.     如果precision为0,则只输出离x最近的整数
  152.     返回值:none
  153. */
  154. inline void output(int precision, double x)
  155. {
  156.     if (x < 0)
  157.     {
  158.         x = -x;
  159.         putchar(‘-‘);
  160.     }
  161.     if (precision)
  162.     {
  163.         // 整数部分
  164.         double intpart;
  165.         x = modf(x, &intpart); // from <math.h>
  166.         unsigned_output((int)intpart);
  167.         //小数部分
  168.         putchar(‘.’);
  169.         for (int i = 1; i < precision && x < dten[i]; ++i)
  170.             putchar(‘0’);// 输出小数点后有多少0
  171.         int ten = 1;
  172.         while (precision–)
  173.             ten *= 10;
  174.         unsigned_output((int)round(x * ten));
  175.     }
  176.     else
  177.         unsigned_output((int)round(x));
  178. }
  179. /*
  180.     输出精度为precision的浮点数(四舍五入),对-0.0输出-0.000000
  181.     如果precision为0,则只输出离x最近的整数
  182.     返回值:none
  183. */
  184. inline void exact_output(int precision, double x)
  185. {
  186.     if (signbit(x)) // from <math.h>, return true if the sign of x is negative(就相当于返回x的符号位)
  187.     {
  188.         x = -x;
  189.         putchar(‘-‘);
  190.     }
  191.     if (precision)
  192.     {
  193.         // 整数部分
  194.         double intpart;
  195.         x = modf(x, &intpart); // from <math.h>
  196.         unsigned_output((int)intpart);
  197.         //小数部分
  198.         putchar(‘.’);
  199.         for (int i = 1; i < precision && x < dten[i]; ++i)
  200.             putchar(‘0’);// 输出小数点后有多少0
  201.         int ten = 1;
  202.         while (precision–)
  203.             ten *= 10;
  204.         unsigned_output((int)round(x * ten));
  205.     }
  206.     else
  207.         unsigned_output((int)round(x));
  208. }
  209. /*
  210.     输出精度为6的浮点数(四舍五入),对-0.0输出0.000000
  211.     返回值:none
  212. */
  213. inline void output(double x)
  214. {
  215.     output(6, x);
  216. }
  217. /*
  218.     输出精度为6的浮点数(四舍五入),并且对-0.0输出-0.000000
  219.     注意:按IEEE 754标准,-0.0和0.0在输出上是有区别的,但是二者实际上是相等的
  220.     返回值:none
  221. */
  222. inline void exact_output(double x)
  223. {
  224.     exact_output(6, x);
  225. }
  226. int main(void)
  227. {
  228.     int t;
  229.     double x;
  230.     unsigned_input(t);
  231.     while (t–)
  232.     {
  233.         input(x);
  234.         output(x);
  235.         putchar(10);
  236.         exact_output(x);// same as printf(“%f”,x);
  237.         putchar(10);
  238.     }
  239.     return 0;
  240. }

标签