c++作业总结3

一、日期类

  • 问题
    当客户端在借书时,需要根据结束当天的日期计算最晚的还书日期。当我们借了多本书时,第二本书的借书日期是第一本书的最晚还书日期。
  • 原因
    重载加法运算符时,没有考虑太多,直接返回的是日期的引用。因为如果返回引用的话不能返回临时变量,只能返货当前对象*this。所以参与加法的日期对象每次加法后内容都会改变,除非加的是0天。
  • 解决方案
    为了让当前日期对象不改变,操作时只能使用this的数据,而不能改变它的数据。加完后的年月日构造一个新的临时对象返回。因此也不能返回引用。
    -代码
  Date operator+(int day1)
    {

        if (isRunNian(year))
        {
            d[1] = 29;
        }
        else
        {
            d[1] = 28;
        }

        int temp;
        int y, m, da;
        y = this->year;
        m = this->month;
        da = this->day;
        temp = this->day + day1;
        if (temp <= d[m - 1])
        {

            da = temp;
        }
        else
        {
            //11/20 65
            day1 = day1 - (d[m - 1] - day);
            m++;
            while (d[-1] < day1)
            {
                m++;
                if (m > 12)
                {
                    m = 1;
                    y++;
                }
                day1 = day1 - d[m - 1];
            }
            da = day1;
        }
        Date msn(y, m, da);
        return msn;
    }

二、操作类

  • 模糊查询
    • 使用的函数:find_if()
    • 步骤:
      • 明确查找的参数
      • 明确要查找的集合。一般是map
      • 明确要查找的区间。找到要查找的区间的起始指针begin和终止指针的下一个位置end。
      • 定义查找函数value_find(string name)。
      • 使用find_if(begin,end,value_find(name))会返回查找到的第一个元素的迭代器。
      • 然后通过循环不断地改变查找的区间。一般是终止区间不变,起始区间++
    • 代码示例:
/*
注意查找区间:除第一次外,以后的区间的开始的地方是查找到的指针的下一个位置
*/
class find_value
{
private:
    const string &value;

public:
    find_value(const string &s) : value(s) {}
    //重载()运算符
    bool operator()(const multimap<string, int>::value_type &p)
    {
        string key = p.first;
        int loc = key.find(value);
        if (loc != key.npos)
            return true;

        return false;
    }
};
    void search3(string name)
    {
        multimap<string,int>::iterator a,b,c,i;
        a=tushuName.begin();
        b=tushuName.end();
        for(i=a;i!=b;)
        {
            c=find_if(i,b,find_value(name));
            if(c!=b)
            {
                   cout<<ts[c->second]<<endl;
                   i=++c;
            }else
            return;
        }
    }

  • 区间查询
    • 知识储备:
      • 通过遍历map,证实了map中的数据是有序的。他会value按照key中<运算符排序。
      • upper_bound(x);
      • lower_bound(y);
    • 代码
    //输入起止出版日期,查询指定时间段出版的图书;
    void search4(Date d1, Date d2)
    {
        multimap<Date, int>::iterator a, b, it;
        a = tushuDate.lower_bound(d1);
        b = tushuDate.upper_bound(d2);
        for (it = a; it != b; it++)
        {
            cout << ts[it->second] << endl;
        }
    }

  • 集合操作:交集
    • 首先,明确是对set进行操作。所以要定义set,并赋值
    • 然后,求交集使用的函数是:set_intersection
    • 代码
   //  按书名+作者查书
    void search5(string s1, string s2)
    {
        //定义一个集合,存放书名在书名此图书在图书向量中的位置
        //在定义一个集合,存放此作者的树在图书向量的位置.
        //求交集
        multiset<int> bname, bzz;
        multimap<string, int>::iterator it1, p1, p2, p, it2, q1, q2, q;
        it1 = tushuName.find(s1);
        if (it1 != tushuName.end())
        {
            p1 = tushuName.lower_bound(s1);
            p2 = tushuName.upper_bound(s1);
            for (p = p1; p != p2; p++)
            {
                bname.insert(p->second);
            }
        }
        it2 = tushuZz.find(s2);
        if (it2 != tushuZz.end())
        {
            q1 = tushuZz.lower_bound(s2);
            q2 = tushuZz.upper_bound(s2);
            for (q = q1; q != q2; q++)
            {
                bzz.insert(q->second);
            }
        }
        vector<int> res;
        vector<int>::iterator i;
        set_intersection(bzz.begin(), bzz.end(), bname.begin(), bname.end(), insert_iterator<vector<int>>(res, res.begin()));
        for (i = res.begin(); i != res.end(); i++)
            cout << ts[*i] << endl;
    }

三、map

  • map遍历的注意点
    • 循环执行的条件是it!=tushuName.end()//tushuName是一个map<string,int>不是it<tushuName.end();
  • 我们可以无序的向map中添加数据,但是map中实际上存的数据是按照key中定义的<运算符排好序的内容。也就是说当使用复杂数据类型存入map中时,必须要重载<运算符,不能重载>运算符
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值