16.62定义你自己版本的hash<Sales_data>,并定义一个Sales_data对象的unordered_multiset。将多条交易记录保存到容器中,并打印其内容。
Sales_data.h
#ifndef SALES_DATA_H #define SALES_DATA_H #include<iostream> #include<string> using namespace std; //template <typename T> class std::hash; class Sales_data { friend class std::hash<Sales_data>; friend Sales_data add(const Sales_data&,const Sales_data&); friend istream &read(istream&,Sales_data &); friend ostream &print(ostream&,const Sales_data&); friend ostream& operator<<(ostream&,const Sales_data&); friend istream& operator>>(istream&,Sales_data&); friend Sales_data operator+(const Sales_data&,const Sales_data&); public: //构造函数 Sales_data() {cout<<"=default"<<endl;} Sales_data(const string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(p*n) {cout<<"construct"<<endl;} Sales_data(istream&); //成员函数 string isbn() const { return bookNo;} Sales_data &combine(const Sales_data&); double avg_price() const; //拷贝构造函数 Sales_data(const Sales_data&); //析构函数 ~Sales_data() { cout<<"destructor"<<endl;} Sales_data& operator+=(const Sales_data&); Sales_data& operator=(string); operator string() const {return bookNo;} operator double() const {return revenue;} private: string bookNo; unsigned units_sold=0; double revenue=0.0; }; Sales_data add(const Sales_data&,const Sales_data&); istream &read(istream &,Sales_data&); ostream &print(ostream&,const Sales_data&); ostream& operator<<(ostream&,const Sales_data&); istream& operator>>(istream&,Sales_data&); Sales_data operator+(const Sales_data&,const Sales_data&); namespace std { template<> struct hash<Sales_data> { typedef size_t result_type; typedef Sales_data argument_type; size_t operator()(const Sales_data &s) const; }; } #endif
Sales_data.cpp
#include"Sales_data.h" Sales_data add(const Sales_data &lhs,const Sales_data &rhs) { Sales_data sum=lhs; sum.combine(rhs); return sum; } istream &read(istream &is,Sales_data &item) { double price=0; is>>item.bookNo>>item.units_sold>>price; item.revenue=price*item.units_sold; return is; } ostream &print(ostream &os,const Sales_data &item) { os<<item.isbn()<<" "<<item.units_sold<<" "<<item.revenue<<" "<<item.avg_price(); return os; } Sales_data::Sales_data(istream& is) { read(is,*this); } Sales_data& Sales_data::combine(const Sales_data& rhs) { units_sold+=rhs.units_sold; revenue+=rhs.revenue; return *this; } double Sales_data::avg_price() const { if(units_sold) return revenue/units_sold; else return 0; } Sales_data::Sales_data(const Sales_data &orig):bookNo(orig.bookNo),units_sold(orig.units_sold),revenue(orig.revenue) { cout<<"copy construct"<<endl; } ostream& operator<<(ostream &os,const Sales_data &item) { os<<item.isbn()<<" "<<item.units_sold<<" "<<item.revenue<<" "<<item.avg_price(); return os; } istream& operator>>(istream &is,Sales_data &item) { double price; is>>item.bookNo>>item.units_sold>>price; if(is) item.revenue=item.units_sold*price; else item=Sales_data(); return is; } Sales_data& Sales_data::operator+=(const Sales_data &rhs) { units_sold+=rhs.units_sold; revenue+=rhs.revenue; return *this; } Sales_data operator+(const Sales_data &lhs,const Sales_data &rhs) { Sales_data sum=lhs; sum+=lhs; return sum; } Sales_data& Sales_data::operator=(string s) { bookNo=s; return *this; } namespace std { size_t hash<Sales_data>::operator()(const Sales_data &s) const { return hash<string>()(s.bookNo)^hash<unsigned>()(s.units_sold)^hash<double>()(s.revenue); } }
main.cpp
#include"Sales_data.h" #include<vector> #include<unordered_set> bool fcn(const Sales_data *trans,Sales_data accum) { Sales_data item1(*trans),item2(accum); return item1.isbn()!=item2.isbn(); } template <typename T> int compare(const T &lhs,const T &rhs) { if(lhs<rhs) return -1; if(rhs<lhs) return 1; return 0; } int main() { string ss="fd"; ss=="fd"; vector<Sales_data> vec; Sales_data s={"sa",7,2}; cout<<endl; //Sales_data *p=new Sales_data(); Sales_data s1=s; Sales_data s2(s); s=s1; cout<<endl; //fcn(&s,s1); cout<<"vector"<<endl; vec.push_back(s); vec.push_back(s1); //vec.push_back(s2); cout<<endl; //delete p; cout<< compare<Sales_data>(Sales_data(),s2)<<endl; cout<<"unordered_multiset"<<endl; unordered_multiset<Sales_data> SDset; while(cin>>s) SDset.insert(s); SDset.insert(s); SDset.insert(s1); SDset.insert(s2); cout<<SDset.size()<<endl; for(auto a:SDset) cout<<a<<endl; return 0; }
16.63定义一个函数模板,统计一个给定值在一个vector中出现的次数。测试你的函数,分别传递给它一个double的vector,一个int的vector以及一个string的vector。
#include<iostream> #include<string> #include<vector> #include<algorithm> using namespace std; template <typename T> int count1(vector<T> &v,T value) { int Count=0; Count=count(v.begin(),v.end(),value); return Count; } template<> int count1(vector<const char *> &v,const char* value) { cout<<"const char *"<<endl; int Count=0; Count=count(v.begin(),v.end(),value); return Count; } int main() { vector<double> dvec={1.2,34.2,4,5.2,34.5}; vector<int> ivec={1,3,4,5,6,7,8,9,0}; vector<string> svec={"a","b","c","d","e","f"}; vector<const char*> cvec={"a","b","c","d","e","f"}; cout<<count1(dvec,5.3)<<endl; cout<<count1(ivec,5)<<endl; cout<<count1<string>(svec,("a"))<<endl; cout<<count1(cvec,"b")<<endl; }