• 第三次作业之Calculator项目随笔


    附:Github的链接:https://github.com/mingyueanyao/object-oriented/tree/master/Calculator

    1、初见题目:

    第一眼看到题目最大的困难就是有很多东西看不懂,因为我C++的自学实际上是很随意的(说好不强求的),截止到题目出现,C++远征攻略的远征起航还没有看完,基本上是一周一章(要是没叫总结的话,说不定还要再看一遍)。。。所以当务之急是赶紧把要用到的东西看完(在群里一不小心地看到了远征攻略要看什么哈)。于是乎我扫了一遍题目就果断放弃去看视频了。

    2、具体操作:

    等我看完了要用的东西,也就是C++视频教程小结(3)里那些东西,再结合群里的只言片语,还是有些想法的。首先这次要建的是一个项目,里面有三个文件,可以确定的是有一个main函数的.cpp文件,至于另外两个类的文件我觉得应该是.h文件,在分文件类外定义里有类似的东西,可以模仿着在.cpp里调用它们。然后就先写出了大致的框架,各个文件各种include先来一遍,再来是mian函数,Scan类和Print类的框架。接下来就要写框架里面的东西,按照顺序看了一遍下来,感觉问题不是很大,比较复杂的也就是Scan里面的那个函数。关于Scan类里面的ToStringQueue函数,我刚开始觉得只要用一个for循环就能把数字和符号提取出来,具体来说长这样(把函数的想法单独拿出来调试):

        #include<stdlib.h>
        #include<iostream>
        #include<string>
        #include<queue>
        using namespace std;
    
        int main()
        {
            string input;
            queue<string>q;
               
            getline(cin,input); 
            for(int i=0;i<input.size();i++)
            {
                q.push(input[i]);       //把string类型的input每个位置的元素都存到队列q里面(感觉数和字符瞬间分开了啊)
                cout<<input[i]<<endl;   //检查传入的元素
            }
                                             
            system("pause");
            return 0;
        };
    

    结果一运行就有问题:

    好像是类型不对,具体怎样也不是很清楚,然后试着把代码部分改成这样:

             string input,str;
             queue<string>q;
               
             getline(cin,input); 
             for(int i=0;i<input.size();i++)
             {
                 str=input[i];
                 q.push(str);
                 cout<<input[i]<<endl;
             }
    

    编译居然通过了,但是样例的运行结果长这样:

    看样子我是太天真了啊,看样子要重新考虑ToStringQueue函数的实现方法了。输入的是四则运算的字符串,那么相对数字来说字符只有加减乘除和括号六个,于是我选择对字符进行特判,用来决定是否存入队列。下面是改来改去的还可以看的代码(主要部分),想法看注释就好:

                    int n=0;
                    string input,str;
                    queue<string>q;
                        
                    getline(cin,input); 
                    for(int i=0;i<input.size();i++)     //逐个扫描input每个位置的元素
                    {                                            
                        if(input[i] == '+'||input[i] == '-'||input[i] == '*'||input[i] == '/'||input[i] == '('||input[i] == ')')
                        {    
                            if(!str.empty())            //第一个有可能是需要特判的特判字符'-',这是避免存入空串
                            {
                                q.push(str);            //把特判字符之前的数字存入队列
                                n++;                    //记录队列长度
                            } 
                            str=input[i];
                            q.push(str);                //元素如果是+、-、*、/、(、)这些字符,直接存入队列
                            n++;                        //记录队列长度
                            str.clear();                //把str变成空串,不然会影响到数字的储存
                        }
                        else
                        {
                            str=str+input[i];           //如果是长得像数字的字符,就把它们接起来变成一个字符
                        }
                    }
                    for(int i=0;i<n;i++)
                    {
                        cout<<q.front()<<endl;          //检查存到队列里的到底是什么
                        q.pop();
                    } 
    

    然后样例的运行结果如下:

    但是我并没有高兴多久,我又随便输入了一个运算调试,结果是这样的:

    重新考虑了一下发现上面的代码只适用于算式的最后是)的算式。。。所以我把部分代码改成了这样:

    else
    {
        str=str+input[i];         //如果是长得像数字的字符,就把它们接起来
        if(i==input.size()-1)
        {
            q.push(str);
        }                         //如果已是最后一位,直接存入队列
    }
    

    然后就可以正确的输出最后是数字的算式了:

    到这里ToStringQueue函数已经差不多了,就开始完善一些细节。我把记录队列长度的n去掉,在for循环里直接用队列的长度q.size(),就是这样:

        for(int i=0;i<q.size();i++)
        {
            cout<<q.front()<<endl;            //检查存到队列里的到底是什么
       	    q.pop();
        }
    

    但是结果却是这样:

    我在代码里加了一句cout<<q.size()<<endl;,运行结果是这样的:

    这到底是为什么。。。最后我试着把代码改成这样:

        int n=q.size();
        for(int i=0;i<n;i++)
        {
            cout<<q.front()<<endl;           //检查存到队列里的到底是什么
            q.pop();
        }
    

    运行结果居然是这样的:

    本着能过就好的心态,直接进入下一阶段。接下来就是数位超过十位报错,这个没什么问题,也就不细说(在代码里面是用cnt来判断的)。最后就是再push到Github上。

    3、最终的代码:

    • Main.cpp
        #include<stdlib.h>
        #include<iostream>
        #include<string>
        #include<queue>
        #include"Scan.h"
        #include"Print.h"
        using namespace std;
    
        int main()
        {
            Scan scan;
            Print print;
            string input;
            queue<string>q;
    
            getline(cin,input);
            q=scan.ToStringQueue(input);
            print.getStringQueue(q);
    
            system("pause");
            return 0;
        } 
    
    • Scan.h
        #include<stdlib.h>
        #include<iostream>
        #include<string>
        #include<queue>
        using namespace std;
    
        class Scan
        {
            public:
                queue<string> ToStringQueue(string input)
                { 	
                    int cnt=0;	   
                    queue<string>q;
                    string str;
    
                    for(int i=0;i<input.size();i++)
                    {
                        if(input[i] == '+'||input[i] == '-'||input[i] == '*'||input[i] == '/'||input[i] == '('||input[i] == ')')
                        {
                            cnt=0;
    
                            if(!str.empty())
                            {
                                q.push(str);
                            }
    
                            str=input[i];
                            q.push(str);
                            str.clear();
                        }
    
                        else
                        {
                             str=str+input[i];
    
                             if(input[i]!='.')
                             {
                              cnt++;
                             }
    
                             if(cnt==11)
                             {
                                 cout<<"wrong input"<<endl;
                                 system("pause");
                             }
    
                             if(i==input.size()-1)
                             {
                                 q.push(str);
                             }
                        }
                   }			
                   return q;
              }
        };
    
    • Print.h
        #include<stdlib.h>
        #include<iostream>
        #include<string>
        #include<queue>
        using namespace std;
    
        class Print
        {
            public:
                void getStringQueue(queue<string>q)
                {
                    int n=q.size();
                    for(int i=0;i<n;i++)
                    {
                        cout<<q.front()<<endl;
                        q.pop();
                    }
                }
          };
    

    4、一些调试样例:

  • 相关阅读:
    [转]SQLSERVER 18056 错误
    【转】 Windows控制台上的UTF8支持
    无法访问共享解决方案之一
    performselectoronmainthread
    iphone开发多线程
    iPad app应用开发系列文章之三 -- iOS的多核编程和内存管理
    ObjectiveC中一种消息处理方法performSelector: withObject:
    UIView你知道多少
    NSBundle介绍
    Blocks,注意
  • 原文地址:https://www.cnblogs.com/mingyueanyao/p/5205354.html
Copyright © 2020-2023  润新知