這些題目都是個人寫的,肯定會有很多問題,歡迎指出錯誤。
10-0 編譯,運行並測試本章中的例程。 < 略>
10-1 重寫9.6節的學生成績,可以生成字母成績。
由於是要修改書上的代碼,代碼比較長,而且直接就將老師給的書上的源代碼拿來進行了寫修改,老師給的課本源代碼是多文件,所以這裏也用的是多文件。
median.h
#ifndef GUARD_median_h
#define GUARD_median_h
#include <algorithm>
#include <stdexcept>
#include <vector>
using std::domain_error;
using std::sort;
using std::vector;
template <class T>
T median(vector<T> v)
{
typedef typename vector<T>::size_type vec_sz;
vec_sz size = v.size();
if (size == 0)
throw domain_error("median of an empty vector");
sort(v.begin(), v.end());
vec_sz mid = size/2;
return size % 2 == 0 ? (v[mid] + v[mid-1]) / 2 : v[mid];
}
#endif
grade.h
#ifndef GUARD_grade_h
#define GUARD_grade_h
// `grade.h'
#include <vector>
double grade(double, double, double);
double grade(double, double, const std::vector<double>&);
#endif
grade.cpp
#include <vector>
#include <stdexcept>
using std::domain_error;
using std::vector;
#include "grade.h"
#include "median.h"
// compute a student's overall grade from midterm and final exam grades and homework grade
double grade(double midterm, double final, double homework)
{
return 0.2 * midterm + 0.4 * final + 0.4 * homework;
}
// compute a student's overall grade from midterm and final exam grades
// and vector of homework grades.
// this function does not copy its argument, because `median' does so for us.
double grade(double midterm, double final, const vector<double>& hw)
{
if (hw.size() == 0)
throw domain_error("student has done no homework");
return grade(midterm, final, median(hw));
}
Student_info.h
#ifndef GUARD_Student_info
#define GUARD_Student_info
#include <string>
#include <vector>
class Student_info {
public:
Student_info(); // construct an empty `Student_info' object
Student_info(std::istream&); // construct one by reading a stream
std::string name() const { return n; }
bool valid() const { return !homework.empty(); }
// as defined in 9.2.1/157, and changed to read into `n' instead of `name'
std::istream& read(std::istream&);
double grade() const; // as defined in 9.2.1/158
private:
std::string n;
double midterm, final;
std::vector<double> homework;
};
bool compare(const Student_info&, const Student_info&);
#endif
Student_info.cpp
#include <iostream>
#include <vector>
#include "grade.h"
#include "Student_info.h"
using std::istream;
using std::vector;
double Student_info::grade() const
{
return ::grade(midterm, final, homework);
}
bool compare(const Student_info& x, const Student_info& y)
{
return x.name() < y.name();
}
Student_info::Student_info(): midterm(0), final(0) { }
Student_info::Student_info(istream& is) { read(is); }
// read homework grades from an input stream into a `vector<double>'
istream& read_hw(istream& in, vector<double>& hw)
{
if (in) {
// get rid of previous contents
hw.clear();
// read homework grades
double x;
while (in >> x)
hw.push_back(x);
// clear the stream so that input will work for the next student
in.clear();
}
return in;
}
istream& Student_info::read(istream& in)
{
in >> n >> midterm >> final;
read_hw(in, homework);
return in;
}
main.cpp
#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
using std::max;
#include "Student_info.h"
#include "median.h"
using std::cin; using std::cout;
using std::domain_error; using std::endl;
using std::setprecision; using std::setw;
using std::sort; using std::streamsize;
using std::string; using std::vector;
int main()
{
vector<Student_info> students;
Student_info record;
string::size_type maxlen = 0;
// read and store the data
while (record.read(cin)) { // changed
maxlen = max(maxlen, record.name().size()); // changed
students.push_back(record);
}
// alphabetize the student records
sort(students.begin(), students.end(), compare);
// write the names and grades
for (vector<Student_info>::size_type i = 0;
i != students.size(); ++i) {
cout << students[i].name() // this and the next line changed
<< string(maxlen + 1 - students[i].name().size(), ' ');
try {
double final_grade = students[i].grade(); // changed
switch((int)final_grade/10)
{
case 10:cout<<"A"<<endl;break;
case 9:cout<<"A"<<endl;break;
case 8:cout<<"B"<<endl;break;
case 7:cout<<"C"<<endl;break;
cout<<"D"<<endl;
}
} catch (domain_error e) {
cout << e.what() << endl;
}
}
return 0;
}
10-2 重寫8.1.1節中的mdian函數,使之可以通過向量或者C++自帶數組以調用該函數。該函數要求可以調用容納有任何算術類型的容器。
分析:因爲可以用於vector,list,以及C++自帶的數組等容器,所以對原來只適用於向量的函數需要進行修改。可以考慮將vector,list,自帶數組中的元素傳遞給median函數後,將裏邊的元素複製到一個新的向量中,而median函數本來就是對一個向量進行操作的。
代碼:
#include<iostream>
#include<vector>
#include<stdexcept>
#include<algorithm>
#include<list>
#include<iterator>
using namespace std;
template<typename T,typename P>
T median(T con,P begin,P end)
{
vector<T>V;
copy(begin,end,back_inserter(V));
if(V.size()==0)
throw domain_error("median is empty");
sort(V.begin(),V.end());
int mid=V.size()/2;
return V.size()%2==0?(V[mid]+V[mid-1])/2:V[mid];
}
int main()
{
int q[10];
vector<int> vec;
list<int> lis;
int a,i=0;
while(cin>>a)
{
*(q+i)=a;
i++;
vec.push_back(a);
lis.push_back(a);
}
int t1=median(q[0],q,q+i);
cout<<"using array:"<<endl;
cout<<t1<<endl;
int t2=median(vec[0],vec.begin(),vec.end());
cout<<"using vector:"<<endl;
cout<<t2<<endl;
int t3=median(*lis.begin(),lis.begin(),lis.end());
cout<<"using list:"<<endl;
cout<<t3<<endl;
return 0;
}
10-3 寫一個測試程序驗證剛纔寫的median函數,確保調用median函數時不會改變容器內的元素的先後順序。
分析:因爲是將容器中的元素複製到了median函數中的新建vector中,所以肯定不會改變裏邊的元素順序,就是簡單寫個測試程序輸出原來容器中的元素。
代碼:
#include<iostream>
#include<vector>
#include<stdexcept>
#include<algorithm>
#include<list>
#include<iterator>
using namespace std;
template<typename T,typename P>
T median(T con,P begin,P end)
{
vector<T>V;
copy(begin,end,back_inserter(V));
if(V.size()==0)
throw domain_error("median is empty");
sort(V.begin(),V.end());
int mid=V.size()/2;
return V.size()%2==0?(V[mid]+V[mid-1])/2:V[mid];
}
int main()
{
int q[10];
vector<int> vec;
list<int> lis;
int a,i=0;
while(cin>>a)
{
*(q+i)=a;
i++;
vec.push_back(a);
lis.push_back(a);
}
int t1=median(q[0],q,q+i);
cout<<"using array:"<<endl;
cout<<t1<<endl;
for(int j=0;j<i;j++)
cout<<*(q+j)<<" ";
cout<<endl<<endl;
int t2=median(vec[0],vec.begin(),vec.end());
cout<<"using vector:"<<endl;
cout<<t2<<endl;
for(int j=0;j<i;j++)
cout<<vec[j]<<" ";
cout<<endl<<endl;
int t3=median(*lis.begin(),lis.begin(),lis.end());
cout<<"using list:"<<endl;
cout<<t3<<endl;
for(list<int>::iterator it=lis.begin();it!=lis.end();it++)
cout<<*it<<" ";
cout<<endl;
return 0;
}
運行結果:這道題目的運行結果正好也可以包含上一道的,所以上一道的就沒貼。