第十一章习题 定义抽象数据类型

1 编译运行讨论的程序

#include <iostream>
#include <cstddef>
#include <memory>
#include <algorithm>

using std::cout;
using std::cin;
using std::endl;
using std::allocator;
using std::max;
using std::uninitialized_fill;
using std::uninitialized_copy;
using std::sort;

template<class T> class Vec{
public:
    typedef T* iterator;
    typedef const T* const_iterator;//迭代器
    typedef size_t size_type;//容器长度
    typedef T value_type;//值类型
    typedef std::ptrdiff_t difference_type;//迭代器相减后的结果
    typedef T& reference;//
    typedef const T& const_reference;

    //构造函数
    Vec(){create();}
    //可以显示的给val值,也可以使用T的默认构造函数来生成这个值
    explicit Vec(std::size_t n, const T& val = T()){create(n, val);}

    //索引(返回引用,是为了避免容器的对象非常大时对它进行复制)
    T& operator[](size_type i) { return data[i];}//读写
    const T& operator[](size_type i) const { return data[i];}//只读
    //动态增加数组
    void push_back(const T& t){
        if(avail == limit){
            grow();
        }
        unchecked_append(t);
    }

    //容器长度
    size_type size() const { return limit - data;}//容器长度

    //返回迭代器类型
    iterator begin(){ return data;}//读写
    const_iterator begin() const { return data;}//只读

    iterator end() { return avail;}
    const_iterator end() const { return avail;}

    //复制构造函数
    Vec(const Vec& v) { create(v.begin(), v.end());}

    //赋值运算符
    Vec& operator=(const Vec&);//允许忽略具体类型的名称(因此没有显示声明返回类型名称)

    //析构函数
    ~Vec(){ uncreate();}



private:
    iterator data;//指针指向Vec的第一个元素
    iterator avail;//指针指向构造元素后面的一个元素
    iterator limit;//指针指向最后一个可获得元素后面的一个元素
    //内存分配工具
    allocator<T> alloc;//控制内存块分配的对象
    //为底层的数组分配空间并对它进行初始化
    void create();
    void create(size_type, const T&);
    void create(const_iterator, const_iterator);

    //删除数组中的元素并释放其占有的内存
    void uncreate();

    //支持push_back函数
    void grow();
    void unchecked_append(const T&);
};
//赋值运算符
template<class T> Vec<T>& Vec<T>::operator=(const Vec& rhs){
    if(&rhs != this){//this:指向操作数对象的指针
        //删除运算符左侧的数组
        uncreate();
        //从右侧复制元素到左侧
        create(rhs.begin(), rhs.end());
    }
    //返回一个指向表达式做操作数对象的一个引用调用
    //该对象生存周期大于赋值操作
    //保证了函数返回的时候不被删除
    return *this;//返回指向的对象
}
//默认构造
template<class T> void Vec<T>::create() {
    data = avail = limit = 0;
}
//带一个参数大小和给初值
template<class T> void Vec<T>::create(size_type n, const T& val){
    data = alloc.allocate(n);
    limit = avail = data + n;
    uninitialized_fill(data, limit, val);
}
//带参数大小
template<class T> void Vec<T>::create(const_iterator i, const_iterator j){
    data = alloc.allocate(j - i);
    limit = avail = uninitialized_copy(i, j, data);
}
//删除对象,释放占用的内存
template<class T> void Vec<T>::uncreate(){
    //alloc.deallocate函数需要一个非零指针作为参数
    //既是它不准备释放任何内存
    if(data){
        //以相反顺序构造函数生成的元素
        iterator it = avail;
        while(it != data){//删除对象
            alloc.destroy(--it);
        }
        //返回占用的所有内存空间
        alloc.deallocate(data, limit - data);//删除未初始化内存
    }
    //重置指针以表明Vec类型对象为空
    data = limit = avail = 0;
}

//push_back函数的成员函数
template<class T> void Vec<T>::grow(){
    //扩展对象大小时,为对象分配实际使用的两倍大小的内存空间
    size_type new_size = max(2 * (limit - data), ptrdiff_t(1));//Vec为空的时候,选择一个元素进行分配
    //分配新的内存空间并将已存在的对象元素内容复制搭配新内存中
    iterator new_data = alloc.allocate(new_size);
    iterator new_avail = std::uninitialized_copy(data, avail, new_data);

    //返回原来的内存空间
    uncreate();

    //重置指针,使其指向新分配的内存空间
    data = new_data;
    avail = new_avail;
    limit = data + new_size;
}

//假设avail指向一片新分配的但尚未初始化的内存空间
template<class T> void Vec<T>::unchecked_append(const T& val){
    alloc.construct(avail++, val);
}


//找最大值
int max_Vec(Vec<int> vec){
   sort(vec.begin(), vec.end());
    return vec[vec.size() - 1];
}

Vec<int> sort_Vec(Vec<int> vec){
    sort(vec.begin(), vec.end());
    return vec;
}

int main(int argc, char** argv){

//测构造函数
    Vec<int> v;//默认构造
    Vec<int> v2(4);//带一个大小参数
    Vec<int> v3(4,6);//带一个大小参数和初值

    //cout << v3.size() << endl;
//    for (Vec<int>::size_type j = 0; j != v3.size(); ++j) {//测索引
//        cout << v3[j] <<" ";
//    }

//测复制构造函数
    v.push_back(3);//测push_back
    v.push_back(1);
    v.push_back(10);
    v.push_back(7);
    //隐式复制操作
//    int d = max_Vec(v);//将vi作为参数传递给max_Vac函数
//    cout << d;
//    Vec<int> v4 = sort_Vec(v);//将sort_Vec函数的返回值赋给v4 //初始化
//    for (Vec<int>::size_type j = 0; j != v4.size(); ++j) {
//        cout << v4[j] <<" ";
//    }
    //显示复制
//    Vec<int> v5 = v3;
//    for (Vec<int>::size_type j = 0; j != v5.size(); ++j) {
//        cout << v5[j] <<" ";
//    }
    //赋值
    Vec<int> v4 = sort_Vec(v);//初始化
    v3 = v4;//赋值操作,已存在的值擦去,以新值代替
        for (Vec<int>::size_type j = 0; j != v3.size(); ++j) {
        cout << v3[j] <<" ";
    }
        
    return 0;
}

2 为什么第九章的Student_info结构中没有定义复制构造函数,也没有定义赋值运算符函数或析构函数?

class Student_info{
public:
    Student_info();//构造一个空的Student_info对象
    Student_info(std::istream&);//读一个流从而构造一个对象
    bool vaild() const{ return ! homework.empty();}//检查对象是否为空
    double grade() const;
    std::istream& read(std::istream& );
    std::string name() const {return n;}//存取器:容许对一部分数据结构的进行访问
private:
    std::string n;
    double midterm, final;
    std::vector<double> homework;
};

因为第九章的Student_info结构没有进行资源管理(如动态分配内存等),因此没有必要专门去写一个析构函数去释放分配的内存,系统会为我们生成相应的默认版本,进行默认操作。

对于这三个函数,因为在类中没有显示地定义这些操作,编译器会自动为类生成相应的默认版本的函数,进行一些默认的操作。

这些默认的函数被定义成一系列的递归操作。

  • 对每个成员数据按照它们相应的类型进行复制、赋值或者删除,如果成员变量是类的对象实例,那么对它们进行复制、赋值与删除时会调用相应类的构造函数、赋值运算符函数或析构函数等。
  • 如果成员变量为C++自带的变量类型,那么在对它们进行复制或赋值时将对它们的值进行复制或复制,而这类变量在删除时不需要任何额外的工作,其他变量类型是指针也不例外。
  • 注意:通过默认析构函数删除一个指针变量时,不会释放指针指向的对象占用的内存空间。

2 为什么该结构中还没有定义一个默认构造函数?

因此类的每个数据成员都有自己的默认构造函数。

3 Student_info的对象在自带调用生成的赋值操作函数具体执行了那些操作?

首先删除一个已经存在的值(运算符左侧对象)然后用一个新值(运算符右侧对象)代替。

4 Student_info中的自动生成的析构函数删除了多少成员变量?

private:
    std::string n;
    double midterm, final;
    std::vector<double> homework;

删除了4个成员变量。

5 在Student_info类中加入计数代码,计算对象被创建、复制、赋值或删除的次数。用这个可以计数的类运行第6章的学生成绩程序。估计出这些不同的类对资源的消耗量。

#ifndef ACM_Student_info
#define ACM_Student_info

#include <string>
#include <vector>
#include <iostream>

class Student_info{
public:
    //构造函数
    Student_info();//默认构造
    Student_info(std::istream&);//输入流构造
    Student_info(const Student_info&);//复制构造
    //赋值运算符
    Student_info& operator=(const Student_info&);
    //析构函数
    ~Student_info();

    std::istream& read(std::istream&);
    double grade() const;
    std::string name() const {return n;}
    bool vail() const {return ! homework.empty();}

    static void reset_count();
    static std::ostream& print_cout(std::ostream&);

private:
    std::string n;
    double midterm, final;
    std::vector<double> homework;

    static int default_constructor_calls;//默认构造
    static int stream_constructor_calls;//输入流构造
    static int copy_constructor_calls;//复制构造
    static int assignment_calls;//赋值运算符
    static int destructor_calls;//析构函数

};

istream& read_hw(istream& , vector<double>& );
double grade(double , double ,const vector<double>& );
double grade(double, double, double);
double median(vector<double >);
#endif
#include <iostream>
using std::cin; using std::cout;
using std::endl; using std::istream;
using std::ostream;

#include <string>
using std::string;

#include <vector>
using std::vector;

#include <stdexcept>
using std::domain_error;

#include <algorithm>
using std::sort;
using std::stable_partition;

#include <chrono>
using std::chrono::steady_clock;

#include <fstream>
using std::ifstream;

#include <sstream>
using std::stringstream;

#include "Student_info.h"

int Student_info::default_constructor_calls;//默认构造
int Student_info::stream_constructor_calls;//输入流构造
int Student_info::copy_constructor_calls;//复制构造
int Student_info::assignment_calls;//赋值运算符
int Student_info::destructor_calls;//析构函数

//构造函数
Student_info::Student_info():midterm(0),final(0) {
    ++default_constructor_calls;
}


Student_info::Student_info(std::istream& is) {
    ++stream_constructor_calls;

    read(is);
}

Student_info::Student_info(const Student_info &s) {
    ++copy_constructor_calls;

    n = s.n;
    midterm = s.midterm;
    final = s.final;
    homework = s.homework;
}
//赋值运算符
Student_info& Student_info::operator=(const Student_info &s) {
    ++assignment_calls;

    if(&s != this){
        n = s.n;
        midterm = s.midterm;
        final = s.final;
        homework = s.homework;
    }
    return *this;
}
//析构函数
Student_info::~Student_info() {
    ++destructor_calls;
}

void Student_info::reset_count() {
    default_constructor_calls = 0;
    copy_constructor_calls = 0;
    assignment_calls = 0;
    stream_constructor_calls = 0;
    destructor_calls = 0;
}

ostream& Student_info::print_cout(std::ostream &os) {
    os << "default_constructor_calls: " << default_constructor_calls <<endl;
    os << "stream_constructor_calls: " << stream_constructor_calls <<endl;
    os << "copy_constructor_calls: " << copy_constructor_calls << endl;
    os << "assignment_calls: " << assignment_calls <<endl;
    os << "destructor_calls: " << destructor_calls <<endl;

    return os;
}

istream& Student_info::read(istream& in){
    in >> n >> midterm >> final;
    read_hw(in, homework);
    return in;
}

double Student_info::grade() const{
    return ::grade(midterm, final, homework);
}

istream& read_hw(istream& in, vector<double>& hw){
    if(in){
        hw.clear();
        double x;
        while(in >> x){
            hw.push_back(x);
        }
        in.clear();
    }
    return in;
}

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(double midterm, double final, double hw){
    return midterm*0.2 + final*0.4 + hw*0.4;
}

double median(vector<double > vec){
    typedef vector<double >::size_type  v_sz;
    v_sz size = vec.size();

    if(size == 0){
        throw domain_error("Median of an empty vector!");
    }

    sort(vec.begin(), vec.end());

    v_sz mid = size/2;

    return size % 2 == 0? (vec[mid] + vec[mid -1])/2 :vec[mid];
}

bool fgrade(const Student_info& s){
    return s.grade() < 60;
}

bool pgrade(const Student_info& s){
    return !fgrade(s);
}

vector<Student_info> extract_fails(vector<Student_info>& students)
{
    vector<Student_info>::iterator iter = stable_partition(students.begin(),students.end(),pgrade);
    vector<Student_info> fail(iter, students.end());
    students.erase(iter, students.end());

    return fail;
}

istream& read(istream& is, vector<Student_info>& v){
    const int BUFFSIZE = 80;
    stringstream ss;
    char buff[BUFFSIZE];

    while(is.getline(buff, BUFFSIZE)){
        ss << buff;
        Student_info students(ss);
        v.push_back(students);
    }
    return is;
}

vector<Student_info> test_Student_info(string file, vector<Student_info>& s){
    ifstream infile(file);
    vector<Student_info> fails;

//    infile.open(file);
    steady_clock::time_point begin = std::chrono::steady_clock::now();
    read(infile, s);
    steady_clock::time_point end = std::chrono::steady_clock::now();
    cout << "Microseconds to read " << file << " into vector = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << endl;

    Student_info::print_cout(cout);
    infile.close();
    infile.clear();

    Student_info::reset_count();

    begin = std::chrono::steady_clock::now();
    fails = extract_fails(s);
    end = std::chrono::steady_clock::now();
    cout << "Microseconds to read " << file <<  " student vector = " <<std::chrono::duration_cast<std::chrono::microseconds>(end-begin).count() <<endl;

    Student_info::print_cout(cout);

    return fails;
}

void test(string file){

    vector<Student_info> students_v;
    test_Student_info(file, students_v);
}

int main(int argc, char ** argv){

//    test("/Users/macbookpro/CLionProjects/ACM/students1000.txt");

    ifstream infile("/Users/macbookpro/CLionProjects/ACM/students10.txt");
//    vector<Student_info> s;
//    read(infile, s);
//    infile.close();
//    infile.clear();

//测复制构造准备
//    Student_info record(infile);
//    infile.close();
//    infile.clear();

//测赋值运算符准备
//    Student_info record(infile);
//    infile.close();
//    infile.clear();
//    Student_info record2(infile);
//    infile.close();
//    infile.clear();
    //测析构函数
    Student_info record(infile);
    vector<Student_info> v;
    v.push_back(record);
    //测10次取中位数
    //单次
    //默认构造:10ms
    //输入流构造:57ms
    //复制构造:2ms
    //赋值运算符:2ms
    //析构函数:2ms
    Student_info::reset_count();
    steady_clock::time_point begin = std::chrono::steady_clock::now();
//    Student_info record;//测默认构造
//    Student_info record(infile);//测输入流构造
//    Student_info record2 = record;//测复制构造
//    record2 = record;//测赋值运算符

    v.pop_back();//测析构函数
    steady_clock::time_point end = std::chrono::steady_clock::now();
    cout << "Microseconds to read into vector = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << endl;
    Student_info::print_cout(cout);
    //测
    return 0;
}

6 在Vec类中增加一个删除其中一个元素的操作

#include <iostream>
#include <cstddef>
#include <memory>
#include <algorithm>

using std::cout;
using std::cin;
using std::endl;
using std::allocator;
using std::max;
using std::uninitialized_fill;
using std::uninitialized_copy;
using std::sort;
using std::ostream;

template<class T> class Vec{
public:
    typedef T* iterator;
    typedef const T* const_iterator;//迭代器
    typedef size_t size_type;//容器长度
    typedef T value_type;//值类型
    typedef std::ptrdiff_t difference_type;//迭代器相减后的结果
    typedef T& reference;//
    typedef const T& const_reference;

    //构造函数
    Vec(){create();}
    //可以显示的给val值,也可以使用T的默认构造函数来生成这个值
    explicit Vec(std::size_t n, const T& val = T()){create(n, val);}
    //复制构造函数
    Vec(const Vec& v) { create(v.begin(), v.end());}
    //赋值运算符
    Vec& operator=(const Vec&);//允许忽略具体类型的名称(因此没有显示声明返回类型名称)
    //析构函数
    ~Vec(){ uncreate();}

    //索引(返回引用,是为了避免容器的对象非常大时对它进行复制)
    T& operator[](size_type i) { return data[i];}//读写
    const T& operator[](size_type i) const { return data[i];}//只读
    //动态增加数组
    void push_back(const T& t){
        if(avail == limit){
            grow();
        }
        unchecked_append(t);
    }
    //清空
    void clear(){
        destory();
    }
    //删除
    void erase(iterator pos){
            destory(pos);
    }
    void erase(iterator b , iterator e){
        destory(b, e);
    }
    //打印数组
    std::ostream& print_vec(std::ostream&);

    //容器长度
    size_type size() const { return limit - data;}//容器长度

    //返回迭代器类型
    iterator begin(){ return data;}//读写
    const_iterator begin() const { return data;}//只读

    iterator end() { return avail;}
    const_iterator end() const { return avail;}

private:
    iterator data;//指针指向Vec的第一个元素
    iterator avail;//指针指向构造元素后面的一个元素
    iterator limit;//指针指向最后一个可获得元素后面的一个元素
    //内存分配工具
    allocator<T> alloc;//控制内存块分配的对象
    //为底层的数组分配空间并对它进行初始化
    void create();
    void create(size_type, const T&);
    void create(const_iterator, const_iterator);

    //删除数组中的元素并释放其占有的内存
    void uncreate();

    //支持push_back函数
    void grow();
    void unchecked_append(const T&);

    //支持clear函数
    void destory();
    //支持erase函数
    iterator destory(iterator);
    iterator destory(iterator, iterator);

};
//赋值运算符
template<class T> Vec<T>& Vec<T>::operator=(const Vec& rhs){
    if(&rhs != this){//this:指向操作数对象的指针
        //删除运算符左侧的数组
        uncreate();
        //从右侧复制元素到左侧
        create(rhs.begin(), rhs.end());
    }
    //返回一个指向表达式做操作数对象的一个引用调用
    //该对象生存周期大于赋值操作
    //保证了函数返回的时候不被删除
    return *this;//返回指向的对象
}
//默认构造
template<class T> void Vec<T>::create() {
    data = avail = limit = 0;
}
//带一个参数大小和给初值
template<class T> void Vec<T>::create(size_type n, const T& val){
    data = alloc.allocate(n);
    limit = avail = data + n;
    uninitialized_fill(data, limit, val);
}
//带参数大小
template<class T> void Vec<T>::create(const_iterator i, const_iterator j){
    data = alloc.allocate(j - i);
    limit = avail = uninitialized_copy(i, j, data);
}
//删除对象,释放占用的内存
template<class T> void Vec<T>::uncreate(){
    //alloc.deallocate函数需要一个非零指针作为参数
    //既是它不准备释放任何内存
    if(data){
        //以相反顺序构造函数生成的元素
        iterator it = avail;
        while(it != data){//删除对象
            alloc.destroy(--it);
        }
        //返回占用的所有内存空间
        alloc.deallocate(data, limit - data);//删除未初始化内存
    }
    //重置指针以表明Vec类型对象为空
    data = limit = avail = 0;
}

//push_back函数的成员函数
template<class T> void Vec<T>::grow(){
    //扩展对象大小时,为对象分配实际使用的两倍大小的内存空间
    size_type new_size = max(2 * (limit - data), ptrdiff_t(1));//Vec为空的时候,选择一个元素进行分配
    //分配新的内存空间并将已存在的对象元素内容复制搭配新内存中
    iterator new_data = alloc.allocate(new_size);
    iterator new_avail = std::uninitialized_copy(data, avail, new_data);

    //返回原来的内存空间
    uncreate();

    //重置指针,使其指向新分配的内存空间
    data = new_data;
    avail = new_avail;
    limit = data + new_size;
}

//假设avail指向一片新分配的但尚未初始化的内存空间
template<class T> void Vec<T>::unchecked_append(const T& val){
    alloc.construct(avail++, val);
}

template <class T>
void Vec<T>::destory() {
    iterator it = avail;
    while(it != data){
        alloc.destroy(--it);
    }
    avail = data;
}

template <class T>
typename Vec<T>::iterator Vec<T>::destory(Vec::iterator pos) {
    if(data && pos != avail){
        alloc.destroy(pos);
        iterator it = pos + 1;
        while(it != avail){
            alloc.construct(pos++, *it++);
            alloc.destroy(pos);
        }
        avail = pos;
    }
    return avail;
}


template <class T>
typename Vec<T>::iterator Vec<T>::destory(Vec<T>::iterator b, Vec<T>::iterator e) {
    if(data && b != avail && b != e){
        iterator  it = b;
        while(it != e){
            alloc.destroy(it);
        }
        while(e != avail){
            alloc.construct(b++, *e);
            alloc.destroy(e++);
        }
        avail = b;
    }
    return avail;
}

template<class T>
ostream& Vec<T>::print_vec(std::ostream &os) {
    if(avail - data > 0){
        const_iterator iter = data;
        os << *iter++;
        while(iter != avail){
            os << " " << *iter++;
        }
        os << std::endl;
    }
    return os;
}


//找最大值
int max_Vec(Vec<int> vec){
    sort(vec.begin(), vec.end());
    return vec[vec.size() - 1];
}

Vec<int> sort_Vec(Vec<int> vec){
    sort(vec.begin(), vec.end());
    return vec;
}

int main(int argc, char** argv){

//测构造函数
    Vec<int> v;//默认构造
//    Vec<int> v2(4);//带一个大小参数
//    Vec<int> v3(4,6);//带一个大小参数和初值

    //cout << v3.size() << endl;
//    for (Vec<int>::size_type j = 0; j != v3.size(); ++j) {//测索引
//        cout << v3[j] <<" ";
//    }

//测复制构造函数
//    v.push_back(3);//测push_back
//    v.push_back(1);
//    v.push_back(10);
//    v.push_back(7);
    //隐式复制操作
//    int d = max_Vec(v);//将vi作为参数传递给max_Vac函数
//    cout << d;
//    Vec<int> v4 = sort_Vec(v);//将sort_Vec函数的返回值赋给v4 //初始化
//    for (Vec<int>::size_type j = 0; j != v4.size(); ++j) {
//        cout << v4[j] <<" ";
//    }
    //显示复制
//    Vec<int> v5 = v3;
//    for (Vec<int>::size_type j = 0; j != v5.size(); ++j) {
//        cout << v5[j] <<" ";
//    }
    //赋值
//    Vec<int> v4 = v;//初始化
//    v3 = v4;//赋值操作,已存在的值擦去,以新值代替
//    for (Vec<int>::size_type j = 0; j != v3.size(); ++j) {
//        cout << v3[j] <<" ";
//    }
    //测删除
    v.push_back(1);//测push_back
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    v.erase(v.begin());
//    v.clear();
    v.print_vec(cout);
//    for (Vec<int>::const_iterator it = v.begin(); it != v.end(); ++it) {
//        cout << *it <<" ";
//    }
    return 0;
}

7 使用Vec重写第九章的Student_info程序和第五章的字符串处理程序

头文件:

#ifndef Vec_H
#define Vec_H

#include <iostream>
#include <cstddef>
#include <memory>
#include <algorithm>

template<class T> class Vec{
public:
    typedef T* iterator;
    typedef const T* const_iterator;//迭代器
    typedef size_t size_type;//容器长度
    typedef T value_type;//值类型
    typedef std::ptrdiff_t difference_type;//迭代器相减后的结果
    typedef T& reference;//
    typedef const T& const_reference;

    //构造函数
    Vec(){create();}
    //可以显示的给val值,也可以使用T的默认构造函数来生成这个值
    explicit Vec(std::size_t n, const T& val = T()){create(n, val);}
    //复制构造函数
    Vec(const Vec& v) { create(v.begin(), v.end());}
    //赋值运算符
    Vec& operator=(const Vec&);//允许忽略具体类型的名称(因此没有显示声明返回类型名称)
    //析构函数
    ~Vec(){ uncreate();}

    //索引(返回引用,是为了避免容器的对象非常大时对它进行复制)
    T& operator[](size_type i) { return data[i];}//读写
    const T& operator[](size_type i) const { return data[i];}//只读
    //动态增加数组
    void push_back(const T& t){
        if(avail == limit){
            grow();
        }
        unchecked_append(t);
    }
    //清空
    void clear(){
        destory();
    }
    //删除
    void erase(iterator pos){
        destory(pos);
    }
    void erase(iterator b , iterator e){
        destory(b, e);
    }
    //出元素
    void pop_back(){
        pop();
    }
    //打印数组
    std::ostream& print_vec(std::ostream&);
    //判断空
    bool empty() const{return !data;}

    //容器长度
    size_type size() const { return limit - data;}//容器长度

    //返回迭代器类型
    iterator begin(){ return data;}//读写
    const_iterator begin() const { return data;}//只读

    iterator end() { return avail;}
    const_iterator end() const { return avail;}

private:
    iterator data;//指针指向Vec的第一个元素
    iterator avail;//指针指向构造元素后面的一个元素
    iterator limit;//指针指向最后一个可获得元素后面的一个元素
    //内存分配工具
    std::allocator<T> alloc;//控制内存块分配的对象
    //为底层的数组分配空间并对它进行初始化
    void create();
    void create(size_type, const T&);
    void create(const_iterator, const_iterator);

    //删除数组中的元素并释放其占有的内存
    void uncreate();

    //支持push_back函数
    void grow();
    void unchecked_append(const T&);

    //支持clear函数
    void destory();
    //支持erase函数
    iterator destory(iterator);
    iterator destory(iterator, iterator);

    //支持pop_back
    void pop();


};
//赋值运算符
template<class T> Vec<T>& Vec<T>::operator=(const Vec& rhs){
    if(&rhs != this){//this:指向操作数对象的指针
        //删除运算符左侧的数组
        uncreate();
        //从右侧复制元素到左侧
        create(rhs.begin(), rhs.end());
    }
    //返回一个指向表达式做操作数对象的一个引用调用
    //该对象生存周期大于赋值操作
    //保证了函数返回的时候不被删除
    return *this;//返回指向的对象
}
//默认构造
template<class T> void Vec<T>::create() {
    data = avail = limit = 0;
}
//带一个参数大小和给初值
template<class T> void Vec<T>::create(size_type n, const T& val){
    data = alloc.allocate(n);
    limit = avail = data + n;
    std::uninitialized_fill(data, limit, val);
}
//带参数大小
template<class T> void Vec<T>::create(const_iterator i, const_iterator j){
    data = alloc.allocate(j - i);
    limit = avail = std::uninitialized_copy(i, j, data);
}
//删除对象,释放占用的内存
template<class T> void Vec<T>::uncreate(){
    //alloc.deallocate函数需要一个非零指针作为参数
    //既是它不准备释放任何内存
    if(data){
        //以相反顺序构造函数生成的元素
        iterator it = avail;
        while(it != data){//删除对象
            alloc.destroy(--it);
        }
        //返回占用的所有内存空间
        alloc.deallocate(data, limit - data);//删除未初始化内存
    }
    //重置指针以表明Vec类型对象为空
    data = limit = avail = 0;
}

//push_back函数的成员函数
template<class T> void Vec<T>::grow(){
    //扩展对象大小时,为对象分配实际使用的两倍大小的内存空间
    size_type new_size = std::max(2 * (limit - data), ptrdiff_t(1));//Vec为空的时候,选择一个元素进行分配
    //分配新的内存空间并将已存在的对象元素内容复制搭配新内存中
    iterator new_data = alloc.allocate(new_size);
    iterator new_avail = std::uninitialized_copy(data, avail, new_data);

    //返回原来的内存空间
    uncreate();

    //重置指针,使其指向新分配的内存空间
    data = new_data;
    avail = new_avail;
    limit = data + new_size;
}

//假设avail指向一片新分配的但尚未初始化的内存空间
template<class T> void Vec<T>::unchecked_append(const T& val){
    alloc.construct(avail++, val);
}

template <class T>
void Vec<T>::destory() {
    iterator it = avail;
    while(it != data){
        alloc.destroy(--it);
    }
    avail = data;
}

template <class T>
typename Vec<T>::iterator Vec<T>::destory(Vec::iterator pos) {
    if(data && pos < avail && pos >= data){
        alloc.destroy(pos);
        iterator it = pos +1;
        while(it != avail){
            alloc.construct(pos++, *it++);
            alloc.destroy(pos);
        }
        avail = pos;
    }
    return avail;
}


template <class T>
typename Vec<T>::iterator Vec<T>::destory(Vec<T>::iterator b, Vec<T>::iterator e) {
    if(data && b < e && e < avail && b >= data){
        iterator it = b;
        while(it != e){
            alloc.destroy(it++);
        }
        while(e != avail){
            alloc.construct(b++, *e);
            alloc.destroy(e++);
        }
        avail = b;
    }
    return avail;
}

template<class T>
std::ostream& Vec<T>::print_vec(std::ostream &os) {
    if(avail - data > 0){
        const_iterator iter = data;
        os << *iter++;
        while(iter != avail){
            os << " " << *iter++;
        }
        os << std::endl;
    }
    return os;
}

template <class T>
void Vec<T>::pop() {
    if(data){
        alloc.destroy(--avail);
    }
}


#endif

重写第九章程序

//
// tudent_info.h
//

#ifndef ACM_Student_info
#define ACM_Student_info

#include <iostream>
#include <string>
#include <vector>
#include "Vec.h"
//struct student_info{
//    std::string name;
//    double midterm, final;
//    std::vector<double> homework;
//
//    std::istream& read(std::istream&);
//    double garde() const;
//};

class Student_info{
public:
    Student_info();//构造一个空的Student_info对象
    Student_info(std::istream&);//读一个流从而构造一个对象
    bool vaild() const{ return ! homework.empty();}//检查对象是否为空
    double grade() const;
    std::istream& read(std::istream& );
    std::string name() const {return n;}//存取器:容许对一部分数据结构的进行访问
private:
    std::string n;
    double midterm, final;
    Vec<double> homework;
};

bool compare(const Student_info&, const Student_info&);

std::istream& read_hw(std::istream&, Vec<double>&);

double grade(double, double, double);
double grade(double, double, const Vec<double>&);

#endif
#include <iostream>
#include <string>
#include <vector>
#include <string>
#include <algorithm>
#include <stdexcept>
#include <iomanip>
#include <ios>
#include "Student_info.h"
#include "Vec.h"

using std::cin; using std::cout;
using std::endl;
using std::istream;
using std::vector;
using std::string;
using std::max;
using std::sort;
using std::domain_error;
using std::setprecision;
using std::streamsize;
//默认构造函数
Student_info::Student_info() :midterm(0), final(0){ }
//带参构造函数
Student_info::Student_info(istream& is) { read(is); }

bool compare(const Student_info& x, const Student_info& y){
    return x.name() < y.name();
}

istream& Student_info::read(istream& in){
    in >> n >> midterm >> final;
    read_hw(in, homework);
    return in;
}

istream& read_hw(istream& in, Vec<double>& hw){
    if(in){
        hw.clear();
        double x;
        while(in >> x){
            hw.push_back(x);
        }
        in.clear();
    }
    return  in;
}

double median(Vec<double> vec){
    typedef Vec<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] + vec[mid -1]) /2 : vec[mid];
}

double Student_info::grade() const {
    //::使用这个名称的某一个版本,而所使用的这个版本不能称为任何事物的成员
    return ::grade(midterm, final, homework);
}

double grade(double midterm, double final, const Vec<double>& hw){
    if(hw.size() == 0)
        throw  domain_error("student has done no homework");
    return grade(midterm, final, median(hw));//如果家庭作业非空,则调用grade3
}//grade2

double grade(double midterm, double final, double hw){
    return midterm * 0.2 + final * 0.4 + hw * 0.4;
}

int main(int argc, char const *argv[]){
    Vec<Student_info> students;
    Student_info record;
    string::size_type maxlen = 0;

    while(record.read(cin)){//
        maxlen = max(maxlen, record.name().size());//
        students.push_back(record);
    }

    sort(students.begin(), students.end(), compare);

    for (Vec<Student_info>::size_type i = 0; i != students.size(); ++i) {
        cout << students[i].name()//
             <<string(maxlen + 1 - students[i].name().size(), ' ');

//        try{
//            double final_grade = students[i].grade();
//            streamsize prec = cout.precision();
//            cout << setprecision(3) << final_grade
//            << setprecision(prec) << endl;
//        }catch(domain_error e){
//            cout << e.what() << endl;
//        }

        if(students[i].vaild() == true){
            double final_grade = students[i].grade();
            streamsize prec = cout.precision();
            cout << setprecision(3) << final_grade
                 << setprecision(prec) << endl;
        }else{
            cout << "homework is empty!"<< endl;
        }
    }
    return  0;
}

重写第五章:

#include <iostream>
#include <string>
#include "Vec.h"
#include <list>
#include <algorithm>
#include <cctype>

using  std::cin; using std::endl;
using std::cout; using std::string;
using std::max;




//分割字符串
Vec<string> split(const string& s){
    Vec<string> ret;
    typedef string::size_type string_size;
    string_size  i = 0;

    while(i != s.size()){
        //忽略前段的空白:[先前的i,i)中全部字符都是空格
        while(i != s.size() && isspace(s[i])){
            i++;
        }
        //找出下一个单词的终结点
        string_size j = i;
        //[先前的j,j)中的任意字符都不是空格
        while(j != s.size() && !isspace(s[j])){
            j++;
        }
        //找到了一些非空白符
        if(i != j){
            ret.push_back(s.substr(i, j - i));
            i = j;
        }
    }
    return ret;
}


//找出向量中最长字符串的长度
string::size_type width(const Vec<string>& v){
    string::size_type  maxlen = 0;
    for (Vec<string>::size_type i = 0; i != v.size(); ++i) {
        maxlen = max(maxlen, v[i].size());
    }
    return maxlen;
}

Vec<string> frame(const Vec<string>& v){
    Vec<string> ret;
    string::size_type maxlen = width(v);
    //输出顶部边框
    string border(maxlen + 4, '*');

    //输出内部的行,每行都用一个星号和一个空格来框起来
    ret.push_back(border);
    for (Vec<string>::size_type i = 0; i != v.size(); ++i) {
        ret.push_back("* "+ v[i]  + string(maxlen - v[i].size(), ' ') + " *");
    }
    //输出底部边框
    ret.push_back(border);
    return  ret;
}

//纵向连接
Vec<string> vcat(const Vec<string>& top, const Vec<string>& bottom){
    Vec<string> ret = top;
    for (Vec<string>::const_iterator it = bottom.begin(); it != bottom.end() ; ++it) {
       ret.push_back(*it);
    }
    //作用同上
//    ret.insert(ret.end(), bottom.begin(), bottom.end());
    return  ret;
}

//横向连接
Vec<string> hcat(const Vec<string>& left, const Vec<string>& right){
    Vec<string>ret;
    //在两幅图案之间留空格
    string::size_type width1 = width(left) + 1;
    //用于遍历left和right的索引
    Vec<string>::size_type i = 0, j = 0;
    while(i != left.size() || j != right.size()){
        string s;
        //如果左侧图案还有待复制的行,则复制一行
        if(i != left.size()){
            s = left[i++];
        }
        //填充至适当长度
        s += string(width1 - s.size(), ' ');
        //如果右侧还有代复制的行,则复制一行
        if(j != right.size()){
            s += right[j++];
        }
        ret.push_back(s);
    }
    return  ret;
}

int main(int argc,const char *argv[]){
    string s;
    while(getline(cin, s)){
        Vec<string> v = split(s);
//        for (vector<string>::size_type i = 0; i != v.size(); ++i) {
//            cout << v[i] <<endl;
//        }
        Vec<string> fra = frame(v);
        Vec<string> col, row;
        col = vcat(v, fra);
        row = hcat(v, fra);
        //打印竖着拼图
        for (Vec<string>::size_type i = 0; i != col.size(); ++i) {
            cout << col[i] << endl;
        }
//        //打印横向拼图
        for (Vec<string>::size_type j = 0; j != row.size(); ++j) {
            cout << row[j] <<endl;
        }
    }
    return 0;
}

8 写一个list类以及它相关的迭代器写一个简化版本

头文件:list.h

#ifndef List_H
#define List_H

#include <memory>

template <class T>
struct Node
{
  T data;
  Node<T>* previous;
  Node<T>* next;

  Node() : data(0), previous(0), next(0) {};
  Node(T d) : data(d), previous(0), next(0) {};
};

template <class T>
class NodeIterator
{

public:
  NodeIterator(Node<T>* d) : data(d) {};

  NodeIterator& operator++();
  NodeIterator& operator--();
  NodeIterator  operator++(int);
  NodeIterator  operator--(int);
  bool operator!=(NodeIterator&) const;
  T& operator*() const;

private:
  Node<T>* data;

};

template <class T>
NodeIterator<T>& NodeIterator<T>::operator++()
{
  data = data->next;
  return *this;
}

template <class T>
NodeIterator<T>& NodeIterator<T>::operator--()
{
  data = data->previous;
  return *this;
}

template <class T>
NodeIterator<T> NodeIterator<T>::operator++(int)
{
  NodeIterator<T> ret(this->data);
  data = data->next;
  return ret;
}

template <class T>
NodeIterator<T> NodeIterator<T>::operator--(int)
{
  NodeIterator<T> ret(this->data);
  data = data->previous;
  return this;
}

template <class T>
bool NodeIterator<T>::operator!=(NodeIterator& rhs) const
{
  return this->data != rhs.data;
}

template <class T>
T& NodeIterator<T>::operator*() const
{
  return data->data;
}

template <class T>
class LList
{
 
public:
  typedef NodeIterator<T> iterator;
  typedef const NodeIterator<T> const_iterator;
  typedef size_t size_type;
  typedef T value_type;

  LList() : front(0), back(0), s(0) {}
  explicit LList(size_type s, const T& t = T()) { create(s, t); }
  LList(const LList& l) { create(l.begin(), l.end()); }

  LList& operator=(const LList&);
  ~LList() { uncreate(); }

  void push_back(const T& t) {
    append(t);
  }

  size_type size() const { return s; }
  iterator begin() { return iterator(front); }
  const_iterator begin() const { return iterator(front); }
  iterator end() { return iterator(0); }
  const_iterator end() const { return iterator(0); }
 
private:
  Node<T>* front;
  Node<T>* back;
  size_type s;

  std::allocator<Node<T>> alloc;

  void create(size_type, const T&);
  void create(iterator, iterator);
  void append(const T&);
  void uncreate();

};

template <class T>
LList<T>& LList<T>::operator=(const LList& l)
{
  if (&l != this) {
    uncreate();
    create(l.begin(), l.end());
  }
  return *this;
}

template <class T>
void LList<T>::create(size_type s, const T& t)
{
  for (size_type i = 0; i < s; i++)
    append(t);
}

template <class T>
void LList<T>::create(iterator b, iterator e)
{
  while (b != e)
    append(*b++);
}

template <class T>
void LList<T>::append(const T& t)
{
  Node<T>* node = new Node<T>(t);

  if (s == 0)
    front = node;
  else if (s == 1)
  {
    node->previous = front;
    back = node;
    front->next = node;
  }
  else
  {
    back->next = node;
    node->previous = back;
    back = node;
  }

  s++;
}

template <class T>
void LList<T>::uncreate()
{
  Node<T>* node = back;

  while (node != 0)
  {
    Node<T>* node_delete = node;
    node = node->previous;
    delete node_delete;
  }

  front = back = 0;
  s = 0;
}

#endif // List_H

测试:

/**

//#include "stdafx.h"//头文件预编译
#include "list.h"

#include <iostream>
using std::cout;
using std::endl;

#include <string>
using std::string;

int main()
{
  LList<int> list;
  list.push_back(5);
  list.push_back(10);
  list.push_back(15);

  LList<int>::iterator iter = list.begin();

  cout << *++iter << endl;
  cout << *--iter << endl;

  while (iter != list.end())
    cout << *iter++ << endl;

  LList<string> stringlist(5, "test");
  LList<string> stringlist_copy = stringlist;
  LList<string>::iterator listIter = stringlist.begin();

  *listIter = "first";

  while (listIter != stringlist.end())
    cout << *listIter++ << endl;

  if (stringlist_copy.size() > 0) {
    listIter = stringlist_copy.begin();
    while (listIter != stringlist.end())
      cout << *listIter++ << endl;
  }

  return 0;
}

9 测试Vec中grow的分配方法对工作效率的提高

本次测试了三组数组:
插入10个元素:
多分配2倍的预分配空间方法:1ms
仅多分配一个的预分配空间方法:2ms
插入100个元素:
多分配2倍的预分配空间方法:4ms
仅多分配一个的预分配空间方法:55ms
插入1000个元素:
多分配2倍的预分配空间方法:24ms
仅多分配一个的预分配空间方法:3062ms
由此可见,预分配两倍内存的方案在插入的数据元素越多的情况下,效率越出众。
测试代码:
头文件:

#ifndef Vec_H
#define Vec_H

#include <iostream>
#include <cstddef>
#include <memory>
#include <algorithm>

template<class T> class Vec{
public:
    typedef T* iterator;
    typedef const T* const_iterator;//迭代器
    typedef size_t size_type;//容器长度
    typedef T value_type;//值类型
    typedef std::ptrdiff_t difference_type;//迭代器相减后的结果
    typedef T& reference;//
    typedef const T& const_reference;

    //构造函数
    Vec(){create();}
    //可以显示的给val值,也可以使用T的默认构造函数来生成这个值
    explicit Vec(std::size_t n, const T& val = T()){create(n, val);}
    //复制构造函数
    Vec(const Vec& v) { create(v.begin(), v.end());}
    //赋值运算符
    Vec& operator=(const Vec&);//允许忽略具体类型的名称(因此没有显示声明返回类型名称)
    //析构函数
    ~Vec(){ uncreate();}

    //索引(返回引用,是为了避免容器的对象非常大时对它进行复制)
    T& operator[](size_type i) { return data[i];}//读写
    const T& operator[](size_type i) const { return data[i];}//只读
    //动态增加数组
    void push_back(const T& t, bool double_grow = true){
        if(avail == limit){
            grow(double_grow);
        }
        unchecked_append(t);
    }
    //清空
    void clear(){
        destory();
    }
    //删除
    void erase(iterator pos){
        destory(pos);
    }
    void erase(iterator b , iterator e){
        destory(b, e);
    }
    //出元素
    void pop_back(){
        pop();
    }
    //打印数组
    std::ostream& print_vec(std::ostream&);
    //判断空
    bool empty() const{return !data;}

    //添加元素:
    void insert(iterator it,const T& t){
        std::ptrdiff_t dis = it - data;
        if(avail == limit) grow(true);
        add(dis, t);
    }
    void insert(iterator out, const_iterator b, const_iterator e){
        std::ptrdiff_t start = out - data;
        std::ptrdiff_t dis = e - b;
        if(dis > 0){//插入区间合法
            while(out + dis >= limit){
                grow();
                out = data + start;//重新更新out
            }
            add(start,b, e);
        }
    }

    //容器长度
    size_type size() const { return limit - data;}//容器长度

    //返回迭代器类型
    iterator begin(){ return data;}//读写
    const_iterator begin() const { return data;}//只读

    iterator end() { return avail;}
    const_iterator end() const { return avail;}

private:
    iterator data;//指针指向Vec的第一个元素
    iterator avail;//指针指向构造元素后面的一个元素
    iterator limit;//指针指向最后一个可获得元素后面的一个元素
    //内存分配工具
    std::allocator<T> alloc;//控制内存块分配的对象
    //为底层的数组分配空间并对它进行初始化
    void create();
    void create(size_type, const T&);
    void create(const_iterator, const_iterator);

    //删除数组中的元素并释放其占有的内存
    void uncreate();

    //支持push_back函数
    void grow(bool);
    void unchecked_append(const T&);

    //支持clear函数
    void destory();

    //支持erase函数
    iterator destory(iterator);
    iterator destory(iterator, iterator);

    //支持pop_back
    void pop();

    //支持insert
    void add(std::ptrdiff_t,const T&);
    void add(std::ptrdiff_t, const_iterator, const_iterator);

};
//赋值运算符
template<class T> Vec<T>& Vec<T>::operator=(const Vec& rhs){
    if(&rhs != this){//this:指向操作数对象的指针
        //删除运算符左侧的数组
        uncreate();
        //从右侧复制元素到左侧
        create(rhs.begin(), rhs.end());
    }
    //返回一个指向表达式做操作数对象的一个引用调用
    //该对象生存周期大于赋值操作
    //保证了函数返回的时候不被删除
    return *this;//返回指向的对象
}
//默认构造
template<class T> void Vec<T>::create() {
    data = avail = limit = 0;
}
//带一个参数大小和给初值
template<class T> void Vec<T>::create(size_type n, const T& val){
    data = alloc.allocate(n);
    limit = avail = data + n;
    std::uninitialized_fill(data, limit, val);
}
//带参数大小
template<class T> void Vec<T>::create(const_iterator i, const_iterator j){
    data = alloc.allocate(j - i);
    limit = avail = std::uninitialized_copy(i, j, data);
}
//删除对象,释放占用的内存
template<class T> void Vec<T>::uncreate(){
    //alloc.deallocate函数需要一个非零指针作为参数
    //既是它不准备释放任何内存
    if(data){
        //以相反顺序构造函数生成的元素
        iterator it = avail;
        while(it != data){//删除对象
            alloc.destroy(--it);
        }
        //返回占用的所有内存空间
        alloc.deallocate(data, limit - data);//删除未初始化内存
    }
    //重置指针以表明Vec类型对象为空
    data = limit = avail = 0;
}

//push_back函数的成员函数
template<class T> void Vec<T>::grow(bool double_grow){
    size_type new_size;
    if(double_grow == true){
        //扩展对象大小时,为对象分配实际使用的两倍大小的内存空间
        //Vec为空的时候,选择一个元素进行分配
        new_size = std::max(2 * (limit - data), std::ptrdiff_t(1));
    }else{
       new_size = limit - data + 1;
    }

    //分配新的内存空间并将已存在的对象元素内容复制搭配新内存中
    iterator new_data = alloc.allocate(new_size);
    iterator new_avail = std::uninitialized_copy(data, avail, new_data);

    //返回原来的内存空间
    uncreate();

    //重置指针,使其指向新分配的内存空间
    data = new_data;
    avail = new_avail;
    limit = data + new_size;
}

//假设avail指向一片新分配的但尚未初始化的内存空间
template<class T> void Vec<T>::unchecked_append(const T& val){
    alloc.construct(avail++, val);
}

template <class T>
void Vec<T>::destory() {
    iterator it = avail;
    while(it != data){
        alloc.destroy(--it);
    }
    avail = data;
}

template <class T>
typename Vec<T>::iterator Vec<T>::destory(Vec::iterator pos) {
    if(data && pos < avail && pos >= data){
        alloc.destroy(pos);
        iterator it = pos +1;
        while(it != avail){
            alloc.construct(pos++, *it++);
            alloc.destroy(pos);
        }
        avail = pos;
    }
    return avail;
}


template <class T>
typename Vec<T>::iterator Vec<T>::destory(Vec<T>::iterator b, Vec<T>::iterator e) {
    if(data && b < e && e < avail && b >= data){
        iterator it = b;
        while(it != e){
            alloc.destroy(it++);
        }
        while(e != avail){
            alloc.construct(b++, *e);
            alloc.destroy(e++);
        }
        avail = b;
    }
    return avail;
}

template<class T>
std::ostream& Vec<T>::print_vec(std::ostream &os) {
    if(avail - data > 0){
        const_iterator iter = data;
        os << *iter++;
        while(iter != avail){
            os << " " << *iter++;
        }
        os << std::endl;
    }
    return os;
}

template <class T>
void Vec<T>::pop() {
    if(data){
        alloc.destroy(--avail);
    }
}

template <class T>
void Vec<T>::add(std::ptrdiff_t dis, const T& val){
    if(dis < avail - data){
        iterator e = avail;
        iterator b = avail -1;
        while(e != data + dis){
            alloc.construct(e--, *b--);
            alloc.destroy(b);
        }
        alloc.construct(data + dis, val);
        ++avail;
    }
}

template <class T>
void Vec<T>::add(std::ptrdiff_t start, Vec<T>::const_iterator b, Vec<T>::const_iterator e) {
    iterator iter = data + start;
    while(b != e){
        *iter++ = *b++;
    }
    avail = iter;
}

#endif

测试函数:

#include <iostream>
#include "Vec.h"
#include <vector>
#include <chrono>
using std::vector;
using std::cin; using std::cout;
using std::endl;
using std::chrono::steady_clock;

void test_push_back(int num){
    Vec<int> v1;
    Vec<int> v2;

    steady_clock::time_point begin = std::chrono::steady_clock::now();
    for (int i = 0; i < num; ++i) {
        v1.push_back(i);
    }
    steady_clock::time_point end = std::chrono::steady_clock::now();
    cout <<  "Microseconds to add "  << num << " to vector using double memory method ="
    << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()<<endl;

    begin = std::chrono::steady_clock::now();
    for (int j = 0; j < num; ++j) {
        v2.push_back(j, false);
    }
    end = std::chrono::steady_clock::now();
    cout <<  "Microseconds to add "  << num << " to vector  without using double memory method ="
    << std::chrono::duration_cast<std::chrono::microseconds>(end-begin).count()<<endl;
}
int main(int argc, char const *argv[]){
    
    //测新push_back
    test_push_back(1000);
    return  0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁星蓝雨

如果觉得文章不错,可以请喝咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值