面向对象程序设计(基于C++)0501 无纸化批阅 paperless.cpp

要求

Define a class paperless to process assignments submitted by students in a website.
定义一个无纸化类来处理学生在网站中提交的作业。
有以下要求:
submit:提交学生id,交作业的编号和作业的名字。
没有作业记录就新建一个,有作业记录就覆盖上一次作业

discard:提交学生id和作业编号
舍弃上一次交的作业,如果没交过throw出异常保证程序正常运行

count:提交作业编号
返回该作业中有多少个学生,要求返回的时间消耗是O(1)

主程序:

//----------------------------------------------------------------------
//
// Test.cpp : Test program for paperless.
//
//----------------------------------------------------------------------

#include <iostream>
#include <string>
using namespace std;

/*************************************************************************/
#include "paperless.h"  // your header file for class paperless
/*************************************************************************/

int main(int argc, char** argv)
{
/*************************************************************************/
    paperless ams;
/*************************************************************************/
    int assignNo; string id,code,skipEOL;
    char c{};

    do
    {
        try
        {  switch(c)
            {
            case 's': // submit
                cout << "ID#: "; cin >> id;
                cout << "Assign#: "; cin >> assignNo; getline(cin,skipEOL);
                cout << "Code: "; getline(cin,code);
        /*************************************************************************/
                ams.submit(id,assignNo,code);
        /*************************************************************************/
                break;
            case 'd': // discard
                cout << "ID#: "; cin >> id;
                cout << "Assign#: "; cin >>  assignNo; getline(cin,skipEOL);
        /*************************************************************************/
                ams.discard(id,assignNo);
        /*************************************************************************/
                break;
            case 'c': // count
                cout << "Assign#: "; cin >>  assignNo;
                cout << "Total updated submissions of assignment #" << assignNo << " : "
        /*************************************************************************/
                        << ams.count(assignNo)
        /*************************************************************************/
                        << endl;getline(cin,skipEOL);
                break;
            }
        }
        // ***** exception handling *****
    /*************************************************************************/
        catch(paperless::bad_paperless)  // catch exceptions related to paperless
    /*************************************************************************/
            { cerr << "bad paperless operation! " << endl; }
        catch(...)  // catch any exceptions
            { cerr << "unknown ERROR" << endl; }

    } while(cout<<endl<<"Enter a command('s','d','c','q'):"<<endl,cin.get(c),c!='q');

    return 0;
}

思路

根据stl容器的特性,可以利用vector【n】来直接访问第n次作业
作业中存放一个map<string,stack<string>> key用来记录学生姓名,而stack拿来记录编号,每次pop和push来进行学生作业的覆盖(其实也可以不pop直接push,不过这样子比较耗费内存)

注意:vector直接使用vector【n】可能会导致越界的情况(并且用【】编译器不会报错,用at()才会报错),所以在访问的时候要记得先resize避免程序的中断

还有就是统计要求时间复杂度O(1),直接返回map的size即可

知识点

vector、map、stack的特性与运用
vector访问的时候注意越界问题
throw扔出来的可以是int、double也可以是自定义的class

代码

注意vector在边界的情况处理,避免越界

#include<iostream>
#include<bits/stdc++.h>
using namespace std;



class paperless
{
private:
    //vector存放编号,然后里面要放名字和代码,map的string是人名,stack存放数据
    vector<map<string,stack<string>>> v;
    long long SIZE = 0;
    
public:
    void submit(string, int, string);//给学生交作业
    void discard(string, int);//丢弃某一个学生某一次作业
    int count(int)const;//统计某一次作业出现的次数

    class bad_paperless{};//定义类型名,让他变成一个类,因为接受的时候接受的也是类型名
};

void paperless::submit(string id,int assignNo,string code)
{
    if(assignNo > SIZE)
    {
        v.resize(assignNo + 10);
        SIZE = assignNo;
    }

    if(v[assignNo - 1][id].empty())
    {
        //找不到证明需要插入新的
        v[assignNo - 1][id].push(code);
        cout << " ok" << endl;
    }
    else
    {
        //更换这次作业的状态,可pop可不pop,取决于要不要改前面的作业
        //v[assignNo][id].pop();
        v[assignNo][id].push(code);
    }
}
void paperless::discard(string id, int assignNo)
{
    if(assignNo > SIZE)
    {
        v.resize(assignNo + 10);
        SIZE = assignNo;
    }
    if(v[assignNo - 1][id].empty())
    {
        throw bad_paperless{};
    }
    else
    {
        v[assignNo - 1].erase(id);
    }

}
int paperless::count(int assignNo)const
{
    if(assignNo > SIZE)
    {
        return 0;
    }
    return v.at(assignNo - 1).size();
}

补充

还可以把头文件的实现写在同名的cpp里面实现更全面的的封装

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值