• 面向对象程序设计课第三次作业


    面向对象程序设计课第三次作业

    更新于 2016/03/24

    初始

    此次的作业是要求实现一个计算器的数据读入和分类功能。
    首先我跟着上一篇随笔中的教程学习了 C++ 的一些基本知识,包括 const 关键字,引用、类、对象的使用等等,然后利用 Dev-C 新建了一个 Caculator 项目,依据作业要求新增了 Scan 类和 Print 类,在 Scan 类下加入一个 ToStringQueue(string _input) 函数,但问题中所提到的使用 ,此前 没有听说过,就查了一下相关资料:一个类似栈的对象,先进先出,有 pop、push、front、back、empty、size 六个函数。初始化的语法是 queue<类型> 队列名

    /******************************************************************************
      FileName: Scan.h
      Author:Ladit    Version :1.1          Date:2016/03/24
      Description:    the scan class file,declare the scan class and function.
      History:
        <author>  <time>   <version>   <description>
        Ladit    16/03/24     1.1      add notes according to the regulations.
    *****************************************************************************/
    
    #ifndef SCAN_H
    #define SCAN_H
    #include <queue>
    #include <string>
    using namespace std;
    
    class Scan
    {
        public:
            Scan();
            ~Scan();
            string ToStringQueue(string _input);
    };
    
    #endif
    
    /******************************************************************************
      FileName: Print.h
      Author:Ladit    Version :1.1          Date:2016/03/24
      Description:    the print class file,declare the print class and function.
      History:
        <author>  <time>   <version>   <description>
        Ladit    16/03/24     1.1      add notes according to the regulations.
    *****************************************************************************/
    
    #ifndef PRINT_H
    #define PRINT_H
    #include <queue>
    #include <string>
    using namespace std;
    
    class Print
    {
        public:
            Print();
            ~Print();
            void getQueueAndOutput(queue<string>_queue);
    };
    
    #endif
    

    至此都没有太大困难,这和上学期 C 语言学习中的 struct 类型十分相似。

    Print 类较为简单,我在其下新建了一个 getQueueAndOutput(queue<string> _queue) 的函数,用以接收存储好的字符串队列并输出。实现的方法也较为简单,利用 cout 循环输出并 pop 队列即可。

    输入部分在 main.cpp 中利用 cin 实现,在此不赘述。

    难点

    比较困难的是实现输入字符串的分类。我的想法是逐个字符读取,判断当前字符和下一个字符是否数字,若当前字符和下一个字符都是数字,则两者相加保存到一个字符串,若当前字符是数字而下一个字符不是数字,则返回当前保存的数字串,若当前字符不是数字,则直接返回当前字符。此外需要注意小数点也需要算作数字。利用两个 bool 变量即可完成判断和动作。此方法明白简单,但有一点是,在 main.cpp 中想要循环 push 进队列,就需要多次用到 ToStringQueue 这个函数,不能处理完后返回队列。因此每次处理完的字符串都必须去除掉已经处理过的字符串,所以我尝试在 main.cpp 中利用循环和暂存有效字符串后覆盖原字符串解决这个问题。然而经过多次尝试编译运行无法成功,出现了许多问题,如无法按期望输出字符、只输出了第一个字符、数字串最后一个数字被丢弃等。经过检查,我认为应该是 main 函数中的操作有误,而且 getQueueAndOutput(queue<string> _queue) 这个函数的逻辑存在问题。

    解决

    经过大神提醒,我发现即使是字符串队列,它的每一个元素的 size 只能是1,所以我想根据字符串队列的 front 元素的长度来循环删除主要字符串中已操作的字符是不可行的。上网查了一下发现 string 对象的确是神器,有一个 erase() 函数可以按不同格式删除字符串的某些内容。如指定位置和删除长度,或指定删除的位置。利用这个函数缩短了好几行代码。
    getQueueAndOutput(queue<string> _queue) 函数中,我改为只判断当前字符是否数字/小数点,若是则加入待输出的字符串,若否则判断是否运算符号,若是则输出,若否则意味着此时是最后一个数字后的第一个字符,应当输出已存的数字字符串,此时还需要注意判断数字串是否超过10位。

    /******************************************************************************
      FileName: Scan.cpp
      Author:Ladit    Version :1.1          Date:2016/03/24
      Description:    the scan function file
      Function List:
        1. scan - scan the input string and return numbers or operators.
      History:
        <author>  <time>   <version>   <description>
        Ladit    16/03/24     1.1      add notes according to the regulations.
    *****************************************************************************/
    
    #include "Scan.h"
    #include <string>
    #include <queue>
    using namespace std;
    
    Scan::Scan() {}
    
    Scan::~Scan() {}
    
    string Scan::ToStringQueue(string _input)
    {
        bool Isnumber;                              //使用 bool 变量判断当前字符是否数字 
        string signstring = "",numstring = "";      //使用两个 string 变量存储需要输出的字符串 
        
        for(int i = 0; i < _input.size(); i++)
        {
            if ((_input[i] >= 48 && _input[i] <= 57) || _input[i] == '.')
            {
                Isnumber = true;                    //判断当前字符是否数字 
            }
            else
            {
                Isnumber = false;
            }
            if (Isnumber)                          //若当前字符是数字则加入待输出的字符串 
            {
                numstring += _input[i];
                
                if (_input[i+1] == '\0')
                {
                    return numstring;
                }
                continue;
            }
            else                                   //否则输出当前非数字的字符或保存的字符串 
            {
                if (numstring.empty())
                {
                    signstring = _input[i]; 
                    return signstring;
                }
                else
                {
                    if (numstring.size() > 10)         //判断数字是否超过10位 
                    {
                        return "ERROR";
                    }
                    else
                    {
                        return numstring;
                    }
                }
            }
        }
    }
    
    /******************************************************************************
      FileName: Print.cpp
      Author:Ladit    Version :1.1          Date:2016/03/24
      Description:    the print function file
      Function List:
        1. print - print the sorted numbers or operators queue.
      History:
        <author>  <time>   <version>   <description>
        Ladit    16/03/24     1.1      add notes according to the regulations.
    *****************************************************************************/
    
    #include "Print.h"
    #include <iostream>
    #include <string>
    #include <queue>
    using namespace std;
    
    Print::Print() {}
    
    Print::~Print() {}
    
    void Print::getQueueAndOutput(queue<string> _queue)
    {
        while(_queue.size())                                       //当队列中有元素时循环输出 
        {
            cout << _queue.front() << endl;
            _queue.pop();
        }
    }
    

    最终的 main 函数:

    /******************************************************************************
      FileName: main.cpp
      Author:Ladit    Version :1.1          Date:2016/03/24
      Description:    the main function file
      Function List:
        1. main - main function 
      History:
        <author>  <time>   <version>   <description>
        Ladit    16/03/24     1.1      add notes according to the regulations.
    *****************************************************************************/
    
    #include "Scan.h"
    #include "Print.h"
    #include <iostream>
    #include <string>
    #include <queue>
    using namespace std;
    
    int main(int argc, char** argv)
    {
        Scan scan;
        Print print;
        string input;
        
        cin >> input;
        
        queue<string> que;
        
        while (!input.empty())                                                      //当剩余字符串不为空时进行循环 
        { 
            if (scan.ToStringQueue(input) == "ERROR")                               //若返回字符串为 ERROR 则报错并退出循环 
            { 
                cout << "ERROR:A number's length is longer than 10." << endl;
                return 0;
            }
            
            que.push(scan.ToStringQueue(input));                                    //将返回的字符串 push 入队列 
            input.erase(0, scan.ToStringQueue(input).size());                       //删除已处理过的字符串 
        }
        
        print.getQueueAndOutput(que);                                               //利用 Print 类中的函数输出队列 
        
        return 0;
    }
    

    在变量命名规则上,函数参数我倾向于在变量前加下划线,以便表明这是一个临时的函数参数,而实际参数用有意义的英文名称,简洁易懂。

    此外,我遇到一些比较粗心的问题,例如忘记写 using namespace std 导致 cout、cin、endl 等无法使用;在 Scan.cpp 和 Print.cpp 中的函数不清楚格式而没写返回值类型,导致无法运行;各种临时变量,如 temp、numstring、signstring 忘记用完需要置空。这些都是一些基本的代码素养,以后需要注意。

    BTW,要向请教过的各位大神表示感谢,例如橘子。

    Github 链接

    https://github.com/ladit/object-oriented/tree/master/Calculator

  • 相关阅读:
    正则化方法:L1和L2 regularization、数据集扩增、dropout
    xgboost原理及应用
    机器学习系列------1. GBDT算法的原理
    c++ stl容器set成员函数介绍及set集合插入,遍历等用法举例
    STL中的set容器的一点总结
    2016-12-17 新浪博客服务器挂掉了,所有博客页面都无法打开
    Centos 6.5 下php5.6.2 的编译安装
    Docker的基本组成
    Docker简介
    基于Dubbo框架构建分布式服务(集群容错&负载均衡)
  • 原文地址:https://www.cnblogs.com/ladit/p/Assignment_3.html
Copyright © 2020-2023  润新知