• 一个字符串题目引发的思考


    ------------恢复内容开始------------

    写在前面

    我是一个退役的ACMer,毕业两年,转战信息学竞赛教育,在给学生找题的时候,做到了一道题,引发一系列思考

    原题

    题目描述

    王老师正在教简单算术运算。细心的王老师收集了i道学生经常做错的口算题,并且想整理编写成一份练习。 编排这些题目是一件繁琐的事情,为此他想用计算机程序来提高工作效率。王老师希望尽量减少输入的工作量,比如5+8的算式最好只要输入5和8,输出的结果要尽量详细以方便后期排版的使用,比如对于上述输入进行处理后输出 5+8=13 以及该算式的总长度6。王老师把这个光荣的任务交给你,请你帮他编程实现以上功能。

    输入格式

    第一行为数值i

    接着的i行为需要输入的算式,每行可能有三个数据或两个数据。

    若该行为三个数据则第一个数据表示运算类型,a表示加法运算,b表示减法运算,c表示乘法运算,接着的两个数据表示参加运算的运算数。

    若该行为两个数据,则表示本题的运算类型与上一题的运算类型相同,而这两个数据为运算数。

    输出格式

    输出2*i行。对于每个输入的算式,输出完整的运算式及结果,第二行输出该运算式的总长度

    题目链接

    https://www.luogu.com.cn/problem/P1957

    解题思路

    1,n组测试数据,果断while(n--)

    2,接住字符串,判断第一个字符串,从而决定第一个数字字符的位置

    3,做好数字转字符串和字符串转数字

    4.完结撒花QAQ

    其实不难,对吗,编辑给的也是倒数第二级的难度,水题。

    思考1 文件读取输入

    我交上去,清一色的WA。好吧我承认我不行了

    第一步,OJ提供判题数据的下载,好吧,复制粘贴控制台,一切正常啊。

    我想起来我毕业设计写的也是oj,当时判题的逻辑是 

    ./a.out <in.txt >out.txt
    

     好吧,我用文件读取数据

    在你main函数第一句话写

    1 freopen("1.in","r",stdin);

    这样你自己不用写输入了

    输出结果还是正常,What???

    思考2 平台问题

    我写了一个编译错误的,交上去,给我一个提示,文件路径是Linux类型的

    好吧,OJ在Linux服务器上面

    打开虚拟机,装Linux,GCC G++ make 

    换行??回车??

    运行我在Windows下写的程序,好,输出不一样

    输出字符串,空的!!!

    我用的是gets(C语言的),我知道要把n后面的换行吃掉,结果还是空,

    干脆删除gets,我一个一个字符来

    cin>>n;
    getchar();//吃换行
    while(n--)
    {
    while(1==1)
    {
    ch=getchar();
    printf("%d",ch);
    
    }
    }

    编译,运行

    死循环,最后一直输出-1

    里层换条件,字符不等于-1

    输出结果

    10 97 32 57 57 32 57 57 57 

    我之前看过数据,

    a 99 999

    就是说 ,从97以后是一一对应的

    难道我没有吃干净

    把吃换行的那一行注释,前面多了个13

    查表 13   10 

    查资料才知道,Windows的 换行以后直接是第二行的行首

    Linux的是两步, 是换行。 是把光标回到行首

    所以对于测试数据1

    1

    a 99 999

    在Windows下

    1 a space 9 9 space 9 9 9

    在Linux下

    1   a space 9 9 space 9 9 9

    这样就解释清楚了,为什么有吃换行还有一个ASCII为10的在

    再吃掉一个

    思考3 gets

          //计算第二个数  
        while (str[i]!=0)
            {
                b=b*10+str[i]-'0';
                ++i;
            }

    在Windows上面一切正常

    但是Linux运行结果是

    99+9955

    又出错了

    让不让玩啦!!!

    在一开始输出str 是999

    计算B的问题

    老办法,输出ASCII

     57 57 57 是999 怎么有个13,

    gets的事情

    学C语言的都明白,gets是读一行字符串,到 结束,而且丢掉

    但是Linux是两个字符啊,所以他只丢掉了 (上面说过,Linux文件里面的回车是 )

    所以这个 是不能读进去的

    修改计算b的循环条件

    while (str[i]>='0')

    终于成功了

    总结

    1,Linux和Windows是不一样的,判题一般是Linux

    2,了解Linux和Windows的回车换行方式,和每一个输入方式对于特殊字符的处理

    3,利用输出中间变量 进行debug的时候,有的字符是输出不出来的,你可以输出ASCII

    AC代码

     1 #include <cstdio>
     2 #include <cmath>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 
     7 using namespace std;
     8 
     9 
    10 int j2(int num)
    11 {
    12     if (num==0)
    13         return 1;
    14     int n=0;
    15     if (num<0)
    16     {
    17         n=1;
    18         num=abs(num);
    19     }
    20     n=n+log10(num)+1;
    21     return n;
    22 }
    23 int main() {
    24     int n;
    25 
    26     //freopen("1.in","r",stdin);
    27     cin>>n;
    28     char last=' ';
    29     getchar();
    30     getchar();
    31     while (n--)
    32     {
    33 
    34         char str[80];
    35         char op;
    36         int a=0,b=0;
    37         int c,len   ;
    38         int start;
    39         gets(str);
    40         if (str[0]>60)
    41         {
    42             op=str[0];
    43             start=2;
    44         }
    45         else
    46         {
    47             op=last;
    48             start=0;
    49         }
    50         int i=start;
    51         while (str[i]!=' ')
    52         {
    53             a=a*10+str[i]-'0';
    54             ++i;
    55         }
    56         i++;
    57         while (str[i]>='0')
    58         {
    59             b=b*10+str[i]-'0';
    60             ++i;
    61         }
    62         last=op;
    63         if (op=='a')
    64         {
    65             printf("%d+%d=%d
    ",a,b,a+b);
    66             c= a+b;
    67         }
    68 
    69         if (op=='b')
    70         {
    71             printf("%d-%d=%d
    ",a,b,a-b);
    72             c= a-b;
    73         }
    74         if (op=='c')
    75         {
    76             printf("%d*%d=%d
    ",a,b,a*b);
    77             c= a*b;
    78         }
    79         len=j2(a)+j2(b)+j2(c)+2;
    80         cout<<len<<endl;
    81 
    82     }
    83     return 0;
    84 }
  • 相关阅读:
    理解Javascript_13_执行模型详解
    vs2005的快捷键
    去除 VS.Net 2003 项目的 VSS 息的脚本
    VS2005的隐藏快捷键
    程序员,你离坐牢还有多远
    对路径XXX的访问被拒绝(文件操作权限)的解决方法
    安装VS2005 SP1之后无法更改或卸载VS2005的处理方法
    强大的.NET反编译工具Reflector及插件
    反编译工具Reflector下载(集成两个常用.net插件,FileGenerator和FileDisassembler)
    两种彻底删除VIEWSTATE的方法
  • 原文地址:https://www.cnblogs.com/Grantlly/p/13160637.html
Copyright © 2020-2023  润新知