Accelerated C++ 15 Revisiting character pictures
来源:互联网 发布:572-393的简便算法 编辑:程序博客网 时间:2024/06/05 02:36
grade.h
#ifndef GUARD_grade_h#define GUARD_grade_h// grade.h#include <vector>double median(std::vector<double>);double grade(double, double, double);double grade(double, double, const std::vector<double>&);double grade(const Student_info&);#endif
grade.cpp
// source file for the grade-ralated functons#include <vector>#include <stdexcept>#include "Student_info.h"#include "median.h"using std::vector; using std::domain_error; using std::sort;double median(vector<double> vec) { typedef vector<double>::size_type vec_sz; vec_sz size = vec.size(); if (size == 0) throw domain_error("median of an empty vector"); sort(vec.begin(), vec.end()); vec_sz mid = size / 2; return size % 2 == 0 ? (vec[mid - 1] + vec[mid]) / 2 : vec[mid];}double grade(double midterm, double final, double homework) { return 0.2 * midterm + 0.4 * final + 0.4 * homework;}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));}double grade(const Student_info& s) { return grade(s.midterm, s.final, s.homework);}
Student_info.h
#ifndef GUARD_Student_info#define GUARD_Student_info// Student_info.h header file#include <iostream>#include <string>#include <vector>class Student_info{public: std::string name() const { return n; } std::istream& read(std::istream&); double grade() const; static bool compare(const Student_info&, const Student_info&);private: std::string n; double midterm, final; std::vector<double> homework;};#endif
Student_info.cpp
// source file for Student_info-related functions#include <vector>#include <iostream>#include "Student_info.h"#include "grade.h"using std::cout; using std::vector; using std::istream;double Student_info::grade() const { return ::grade(midterm, final, homework);}bool Student_info::compare(const Student_info& x, const Student_info& y) { return x.n < y.n;}istream& read_hw(istream& in, vector<double>& hw) { // read and store the homework grades cout << "Enter all your homework grades, " "followd by end-of-file: "; 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& is) { // read and store the student's name and midterm and final exam grades cout << "Please enter your first name, midterm and final exam grades: "; is >> n >> midterm >> final; read_hw(is, homework); return is;}
Pic.h
#ifndef GUARD_Pic_h#define GUARD_Pic_h#include <iostream>#include <vector>#include <string>#include <algorithm>#include "Ptr.h"// forward declarationclass Picture;class Pic_base { friend std::ostream& operator<<(std::ostream&, const Picture&); friend class Frame_Pic; friend class HCat_Pic; friend class VCat_Pic; friend class String_Pic; private: // no public interface(except for the destrctor) typedef std::vector<std::string>::size_type ht_sz; typedef std::string::size_type wd_sz; virtual wd_sz width() const = 0; virtual ht_sz height() const = 0; virtual void display(std::ostream&, ht_sz, bool) const = 0; public: virtual ~Pic_base() { } protected: static void pad(std::ostream&, wd_sz, wd_sz);};void Pic_base::pad(std::ostream& os, wd_sz beg, wd_sz end) { while (beg != end) { os << " "; ++beg; }}class Frame_Pic: public Pic_base { friend Picture frame(const Picture&); // no public interface Ptr<Pic_base> p; Frame_Pic(const Ptr<Pic_base>& pic): p(pic) { } wd_sz width() const { return p->width() + 4; } ht_sz height() const { return p->height() + 4; } void display(std::ostream&, ht_sz, bool) const;};void Frame_Pic::display(std::ostream& os, ht_sz row, bool do_pad) const { if (row >= height()) { // out of range if (do_pad) pad(os, 0, width()); } else if (row == 0 || row == height() - 1) { // top or bottom row os << std::string(width(), '*'); } else if (row == 1 || row == height() - 2) { // second from top or bottom row os << "*"; pad(os, 1, width() - 1); os << "*"; } else { // interior row os << "* "; p->display(os, row - 2, true); os << " *"; }}class VCat_Pic: public Pic_base { friend Picture vcat(const Picture&, const Picture&); Ptr<Pic_base> top, bottom; VCat_Pic(const Ptr<Pic_base>& t, const Ptr<Pic_base>& b): top(t), bottom(b) { } wd_sz width() const { return std::max(top->width(), bottom->width()); } ht_sz height() const{ return top->height() + bottom->height(); } void display(std::ostream&, ht_sz, bool) const;};void VCat_Pic::display(std::ostream& os, ht_sz row, bool do_pad) const { wd_sz w = 0; if (row < top->height()) { // we are in the top subpicture top->display(os, row, do_pad); w = top->width(); } else if (row < height()) { // we are in the bottom subpicture bottom->display(os, row - top->height(), do_pad); w = bottom->width(); } if (do_pad) pad(os, w, width());}class HCat_Pic: public Pic_base { friend Picture hcat(const Picture&, const Picture&); Ptr<Pic_base> left, right; HCat_Pic(const Ptr<Pic_base>& l, const Ptr<Pic_base>& r): left(l), right(r) { } wd_sz width() const { return left->width() + right->width(); } ht_sz height() const { return std::max(left->height(), right->height()); } void display(std::ostream&, ht_sz, bool) const;};void HCat_Pic::display(std::ostream& os, ht_sz row, bool do_pad) const { left->display(os, row, do_pad || row < right->height()); right->display(os, row, do_pad);}class String_Pic: public Pic_base { friend class Picture; std::vector<std::string> data; String_Pic(const std::vector<std::string>& v): data(v) { } wd_sz width() const; ht_sz height() const { return data.size(); } void display(std::ostream&, ht_sz, bool) const;};Pic_base::wd_sz String_Pic::width() const { Pic_base::wd_sz n = 0; for (Pic_base::ht_sz i = 0; i != data.size(); ++i) n = std::max(n, data[i].size()); return n;}void String_Pic::display(std::ostream& os, ht_sz row, bool do_pad) const { wd_sz start = 0; // write the row if we're still in range if (row < height()) { os << data[row]; start = data[row].size(); } // pad the output if necessary if (do_pad) pad(os, start, width());}class Picture { friend std::ostream& operator<<(std::ostream&, const Picture&); friend Picture frame(const Picture&); friend Picture hcat(const Picture&, const Picture&); friend Picture vcat(const Picture&, const Picture&); public: Picture(const std::vector<std::string>& v = std::vector<std::string>()): p(new String_Pic(v)) { } private: Picture(Pic_base* ptr): p(ptr) { } Ptr<Pic_base> p;};Picture frame(const Picture& pic) { return new Frame_Pic(pic.p);}Picture hcat(const Picture& l, const Picture& r) { return new HCat_Pic(l.p, r.p);}Picture vcat(const Picture& t, const Picture& b) { return new VCat_Pic(t.p, b.p);}std::ostream& operator<<(std::ostream& os, const Picture& picture) { const Pic_base::ht_sz ht = picture.p->height(); std::endl; for (Pic_base::ht_sz i = 0; i != ht; ++i) { picture.p->display(os, i, false); os << std::endl; } return os;}#endif
Ptr.h
#ifndef GUARD_Ptr_h#define GUARD_Ptr_h// Ptr.h#include <iostream>#include <stdexcept>template <typename T> class Ptr { public: // new member to copy the object conditionally when needed void make_unique() { if (*refptr != 1) { --*refptr; refptr = new size_t(1); p = p ? p->clone() : 0; } } // same as Ref_handle Ptr(): p(0), refptr(new size_t(1)) { } Ptr(T* t): p(t), refptr(new size_t(1)) { } Ptr(const Ptr& h): p(h.p), refptr(h.refptr) { ++*refptr; } Ptr& operator=(const Ptr&); ~Ptr(); operator bool() const { return p; } T& operator*() const; T* operator->() const { if (p) return p; throw std::runtime_error("unbound Ptr"); } private: T* p; std::size_t* refptr;};template <typename T> Ptr<T>& Ptr<T>::operator=(const Ptr& rhs) { ++*rhs.refptr; // free the left-hand side, destroying pointers if appropriate if (--*refptr == 0) { delete refptr; delete p; } // copy in values from the right-hand side refptr = rhs.refptr; p = rhs.p; return *this;}template <typename T>T& Ptr<T>::operator*() const { if (p) return *p; throw std::runtime_error("unbound Ptr");}template <typename T>Ptr<T>::~Ptr() { if (--*refptr == 0) { delete refptr; delete p; }}#endif
main.cpp
// main.cpp#include "Pic.h"// #include "median.h"// #include "grade.h"// #include "Ptr.h"#include "Student_info.h"#include <algorithm>using std::vector; using std::string; using std::cin;using std::cout; using std::endl; using std::sort;Picture histogram(const vector<Student_info>& students) { Picture names; Picture grades; // for each student for (vector<Student_info>::const_iterator it = students.begin(); it != students.end(); ++it) { // create vertically concatenated pictures of the names and grades names = vcat(names, vector<string>(1, it->name())); grades = vcat(grades, vector<string>(1, " " + string(it->grade() / 5, '='))); } // horizontally concatenate the name and grade pictures to combine them return hcat(names, grades);}int main() { vector<Student_info> students; Student_info s; // read the names and grades while (s.read(cin)) students.push_back(s); // put the students in alphabetical order sort(students.begin(), students.end(), Student_info::compare); // write the names and histograms cout << frame(histogram(students)) << endl; return 0;}
阅读全文
0 0
- Accelerated C++ 15 Revisiting character pictures
- pictures
- Pictures
- 读《Accelerated C++》有感
- 【Accelerated C++】读书笔记(一)
- 【Accelerated C++】读书笔记(二)
- 【Accelerated C++】读书笔记(三)
- 【Accelerated C++】读书笔记(四)
- 【Accelerated C++】读书笔记(五)
- 【Accelerated C++】读书笔记(六)
- 【Accelerated C++】重点回顾
- 《Accelerated C++》 笔记摘录
- 《accelerated c++》---------第六章
- Accelerated C++Exercises' Resolutions
- 【Accelerated C++】重点回顾
- Accelerated C++<3-2>
- Accelerated C++<4-1>
- Accelerated C++<4-2>
- 20. Valid Parentheses
- Ubuntu & GitLab CI & Docker & ASP.NET Core 2.0 自动化发布和部署(1)
- 关于Thinkpad E540 电脑更换固态硬盘的相关问题
- BZOJ[3038]上帝造题的7分钟2 树状数组+并查集
- KMP算法详解
- Accelerated C++ 15 Revisiting character pictures
- Java入门(7)——循环和debug 调试
- JDBC批量插入数据优化,使用addBatch和executeBatch
- 系统学习C++(1)
- codevs 1002 搭桥 【最小生成树】解题报告
- linux上面运行python抓取数据时由于chromedriver和chromium没有关闭导致的内存泄漏的问题解决方案
- 黑色星期五
- Ubuntu16.04配置anaconda环境
- Error:(1, 0) Plugin with id 'com.android.application' not found