zoukankan      html  css  js  c++  java
  • 快读快写 模板

    1. #include<cstdio>        
    2. #include<iostream>        
    3. #include<cctype>        
    4. using namespace std;        
    5. int read()        
    6. {        
    7.     int s = 0, f = 1;        
    8.     char ch = getchar();        
    9.     while(!isdigit(ch)) {        
    10.         if(ch == '-') f = -1;        
    11.         ch = getchar();        
    12.     }        
    13.     while(isdigit(ch)) {        
    14.         s = s * 10 + ch - '0';        
    15.         ch = getchar();        
    16.     }        
    17.     return s * f;        
    18. }        
    19. void write(int x)        
    20. {        
    21.     if(x < 0) {        
    22.         putchar('-');        
    23.         x = -x;        
    24.     }        
    25.     if(x > 9)        
    26.         write(x/10);        
    27.     putchar(x % 10 + '0');        
    28.     return;        
    29. }        
    30. int main()        
    31. {        
    32.     int a;        
    33.     a = read();        
    34.     write(a);        
    35.     return 0;        
    36. }      

    一些问题:

    1. 快读快写比标准输入输出流以及C的格式化输入输出要快,主要是由于直接利用了单个字符操作,并且适用范围仅限所定义的返回类型与输出类型,牺牲了标准输入输出的普适性而换取了效率,在算法竞赛中具有广泛的应用空间。

    2. 快读、快写函数的实现分别用到了循环和递归,从理论上讲无法完成内联,inline建议不会被编译器采纳;通过在vijos上对某一需要大量输入的题目使用快读进行测试,可以发现read()前加入或不加入inline的效率几乎相同。由此可以判断inline大概率被忽略,或是函数调用和返回的时间微不足道,个人认为inline没有必要。(不理解的同学可从资料和各大博客了解内联函数的相关知识)

    3. 该方法利用了cctype库中的字符判断函数isdigit(),其效率与手写ASCII码判断几乎不相上下,甚至更快,可以说同时实现了简洁与快捷,建议使用。

    4. 理论上效率较高的写法是将read中所定义的变量加入寄存器建议,但是实测的效率相差并不大。依然有指令被编译器忽略的可能性,因此加不加入就看自己的想法了。

    5. int read(void)函数也可以写成void read(&int)的形式(对地址进行直接赋值操作),效率方面没有太大差别,可以按照个人爱好采用不同风格。

    6. 一种使用fread()函数可以进一步显著提升读入效率,但写法较为复杂,且需要额外开辟内存,出错率高,在OI中用途有限,有兴趣的同学可以自行学习了解。

    太原五中

    袁盛琪

    2019年3月26日

    ----------------------------------------------

    2019.7.7 做一个补充

    1. template <typename T>    
    2. void read(T &x) {    
    3.     x = 0;    
    4.     int f = 1;    
    5.     char ch = getchar();    
    6.     while (!isdigit(ch)) {    
    7.         if (ch == '-') f = -1;    
    8.         ch = getchar();    
    9.     }    
    10.     while (isdigit(ch)) {    
    11.         x = x * 10 + (ch ^ 48);    
    12.         ch = getchar();    
    13.     }    
    14.     x *= f;    
    15.     return;    
    16. }   

    以上是使用模板template的快速读入。它可以读取任何格式的整型数据。

    再说明一个以前留下的小问题:register编译建议是在每个函数进程中重新定义的,即便是读入int64范围的数据,函数变量也最多会迭代20次左右,每次把它定义在寄存器里其实有些鸡肋。

    ----------------------------------------------

    附上使用模板的快写。

     
    1. template <typename T>  
    2. void write(T x)    
    3. {    
    4.     if(x < 0) {    
    5.         putchar('-');    
    6.         x = -x;    
    7.     }    
    8.     if(x > 9)    
    9.         write(x/10);    
    10.     putchar(x % 10 + '0');    
    11.     return;    
    12. }    
  • 相关阅读:
    windows配置solr5.5.2(不通过tomcat,使用内置jetty)
    6月8日云栖精选夜读:mac下eclipse配置tomcat无法启动问题
    零配置部署 React
    万亿级数据洪峰下的分布式消息引擎
    ENode 2.0
    WannaCry感染文件恢复方法_企业再也不用愁了!
    中国最强的人工智能学术会议来了
    1篇文章看懂峰值带宽、流量、转码、连麦、截图五大直播计费方式
    CSS基础(三)
    CSS基础(三)
  • 原文地址:https://www.cnblogs.com/TY02/p/10606685.html
Copyright © 2011-2022 走看看