0903,LIST(merge,splice,sort,unique),SET(insert,erase)

目录

03_vector_delete.cc

04_vector_shrink.cc

05_vec_emplace_back.cc

06_listspec_splice.cc

07_classstruct.cc

08_set.cc

09_setErase.cc

作业

[01 STL中的容器包括哪些?各自具有哪些特点?](#01 STL中的容器包括哪些?各自具有哪些特点?)

[02 题目:编写代码:将一个list中的char *指针元素赋值给一个vector中的string。](#02 题目:编写代码:将一个list中的char *指针元素赋值给一个vector中的string。)

[03 编程题:从标准输入读取 string 序列,存入一个 deque 中。编写一个循环,用迭代器打印 deque 中的元素。](#03 编程题:从标准输入读取 string 序列,存入一个 deque 中。编写一个循环,用迭代器打印 deque 中的元素。)

[04 编程题:从一个 list 拷贝元素到两个 deque 中。值为偶数的所有元素都拷贝到一个 deque 中,而奇数值元素都拷贝到另一个 deque 中。](#04 编程题:从一个 list 拷贝元素到两个 deque 中。值为偶数的所有元素都拷贝到一个 deque 中,而奇数值元素都拷贝到另一个 deque 中。)

[05 题目:学生成绩管理系统](#05 题目:学生成绩管理系统)

03_vector_delete.cc

cpp 复制代码
#include <iostream>
#include <vector>
#include <deque>
#include <list>
using std::cout;
using std::endl;
using std::vector;
using std::deque;
using std::list;

template <typename Container>
void display(const Container & con){
    for(auto &ele: con){
        cout<<ele<<" ";
    }
    cout<<endl;
}


//vector ++
//---------------------------------//
void test1(){
    vector<int> v={1,2,2,2,2,4,6,8,2,3};
    display(v);
    //需求:delete all 2
    for(auto it=v.begin();it!=v.end();++it){
        if(*it==2){
            v.erase(it);//不能删除连续重复的元素
                        //迭代器会后移(for循环里面的++it)
            /* --it;//段错误 */
            //删除迭代器指向的元素时,后面的迭代器也会受到影响
            //指向的元素发生了改变
        }    
    }
    display(v);
    cout<<endl;
}


//vector no ++
//---------------------------------//
void test(){
    vector<int> v={1,2,2,2,2,4,6,8,2,3};
    display(v);
    for(auto it=v.begin();it!=v.end();){
        if(*it==2){
            v.erase(it);
        }else{
            ++it;
        }
    }
    display(v);
    cout<<endl;
}


//deque no ++
//---------------------------------//
void test2(){
    deque<int> v={1,2,2,2,2,4,6,8,2,3};
    display(v);
    for(auto it=v.begin();it!=v.end();){
        if(*it==2){
            v.erase(it);
        }else{
            ++it;
        }
    }
    display(v);
    cout<<endl;
}


//deque++
//---------------------------------//
void test3(){
    deque<int> v={1,2,2,2,2,4,6,8,2,3};
    display(v);
    for(auto it=v.begin();it!=v.end();++it){
        if(*it==2){
            v.erase(it);
        }
    }
    display(v);
    cout<<endl;
}
//坏,能正确删除是因为?删除前半部分的内容,
//将前面的元素后移了?所以能正确删除

//deque++  behind
//---------------------------------//
void test4(){
    deque<int> v={1,2,4,6,8,2,2,2,2,2,3};
    display(v);
    for(auto it=v.begin();it!=v.end();++it){
        if(*it==2){
            v.erase(it);
        }
    }
    display(v);
    cout<<endl;
}
//好好好,没有完全删除后面的2





//list++
//---------------------------------//
void test5(){
    list<int> v={1,2,2,2,2,4,6,8,2,3};
    display(v);
    for(auto it=v.begin();it!=v.end();++it){
        if(*it==2){
            it=v.erase(it);
            //链表删除掉节点之后,节点失效(迭代器失效)
            //需要重新接收erase的返回值(新的有效的迭代器
        }
    }
    display(v);
    cout<<endl;
}

//list no ++
//---------------------------------//
void test6(){
    list<int> v={1,2,2,2,2,4,6,8,2,3};
    display(v);
    for(auto it=v.begin();it!=v.end();){
        if(*it==2){
            it=v.erase(it);
        }else{
            ++it;
        }
    }
    display(v);
    cout<<endl;
}


//---------------------------------//
int main(void)
{
    test();
    test1();//vector ++
    test2();//deque else
    test3();//deque++
    test4();//deque++  behind
    test5();//list++
    test6();//list else
    return 0;
}

04_vector_shrink.cc

cpp 复制代码
#include <iostream>
#include <vector>
#include <deque>
#include <list>
using std::cout;
using std::endl;
using std::vector;
using std::list;
using std::deque;

template <typename Container>
void display(const Container & con){
    for(auto &ele: con){
        cout<<ele<<" ";
    }
    cout<<endl;
}
template <typename Container>
void display_cap(const Container & con){
    display(con);
    cout<<"size::"<<con.size()<<endl;
    /* cout<<"capacity::"<<con.capacity()<<endl; */
}
template <typename Container>
void re_resize( Container & con){
    con.resize(20);
    display_cap(con);
    con.resize(2);
    display_cap(con);
}




void test(){
    cout<<"<<<<<<<<<<<<<<<<vector first number addr"<<endl;
    vector<int> num3{4,5,6,7,8,9};
    display_cap(num3);
    cout<<"capacity::"<<num3.capacity()<<endl;
    num3.clear();
    display_cap(num3);
    cout<<"capacity::"<<num3.capacity()<<endl;
    num3.shrink_to_fit();
    display_cap(num3);
    cout<<"capacity::"<<num3.capacity()<<endl;

    re_resize(num3);
    cout<<"capacity::"<<num3.capacity()<<endl;


    cout<<endl<<endl;
    //-----------------------------//
    cout<<"<<<<<<<<<<<<<<<<<<list push anywhere"<<endl;
    list<int> num2{0,1,4,5,6,7,8,9};
    display_cap(num2); //list no capacity()
    num2.clear();
    display_cap(num2);
    /* num2.shrink_to_fit();//list no shrink */

    re_resize(num2);


    cout<<endl<<endl;
    //-----------------------------//
    cout<<"<<<<<<<<<<<<<<<<<<deque push anywhere"<<endl;
    deque<int> num1{0,1,2,3,4,5,6,7};
    display_cap(num1);//deque no capacity()
    num1.clear();
    display_cap(num1);
    num1.shrink_to_fit();//list no shrink

    re_resize(num1);

}

int main(void)
{
    test();
    return 0;
}

05_vec_emplace_back.cc

cpp 复制代码
#include <iostream>
#include <vector>
#include <deque>
#include <string.h>
#include <random>
using std::cout;
using std::endl;
using std::vector;
using std::deque;
using std::ostream;

#define  PER_NUM 5
#define  SCO_NUM 10

template <typename Container>
void display(const Container & con){
    for(auto &ele: con){
        cout<<ele<<" ";
    }
    cout<<endl<<endl;
}

//-------------------------------------//
class AA{
public:
    /* AA() */
    /*     :_aa(0),_bb(0) */
    /* {cout<<"AA()"<<endl;} */
    AA(int a=0,int b=0)
        :_aa(a),_bb(b)
    {cout<<"AA(int ,int)"<<endl;}
    AA(const AA & a)
        :_aa(a._aa),_bb(a._bb)
    {cout<<"AA(const AA &)"<<endl;}
    AA(const AA && a)
        :_aa(a._aa),_bb(a._bb)
    {cout<<"AA(const AA &&)"<<endl;}
    friend ostream & operator<<(ostream & os,const AA & p);
private:
    int _aa;
    int _bb;
};
ostream & operator<<(ostream & os,const AA  & p){
    os<<p._aa<<"--"<<p._bb<<"  ";
    return os;
}


//-------------------------------------//
class Person{
public:
    /* Person() */
    /*     :_name(new char[5]()),_score(0) */
    /* { */
    /*     strcpy(_name,"haha"); */
    /*     cout<<"Person()"<<_name<<endl; */
    /* } */
    Person(const char* name="xixi",const int sc=0)
        :_name(new char[strlen(name)+1]()),_score(sc)
    {
        strcpy(_name,name);
        cout<<"Person(char* ,int)"<<endl;
    }
    Person(const Person & p)
        :_name(new char[strlen(p._name)+1]()),_score(p._score)
    {
        strcpy(_name,p._name);
        cout<<"Person(const Person &)"<<endl;
    }//vector初始化使用拷贝构造
    ~Person(){
        if(_name){
            delete []  _name;
            _name=nullptr;
        }
    }
    Person & operator=(const Person & p){
        if(this!=&p){
            delete [] _name;
            _name=new char[strlen(p._name)+1]();
            strcpy(_name,p._name);
            _score=p._score;
        }
        return *this;
    }
    void p_sc(int sc){
        _score=sc;
    }
    friend ostream & operator<<(ostream & os,const Person & p);
private:
    char* _name;
    int _score;
};
ostream & operator<<(ostream & os,const Person & p){
    os<<p._name<<"--"<<p._score<<"  ";
    return os;
}


//-------------------------//
void get_sc(vector<Person>  & con){
    for(auto & ele: con){
        cout<<ele<<" ";
    }
    cout<<endl;
}

//-------------------------//
void test(){
    vector<Person> p1;
    /* p1.push_back(1); */
    /* p1.push_back("jiajia",100); */
    p1.push_back(Person("yueyue",101));
    display(p1);
    //下面这俩还多调用了一个拷贝??
    p1.emplace_back(Person("kaixin",102));
    display(p1);

    p1.emplace_back("jiajia",103);
    display(p1);
    


    vector<AA> a1;
    /* a1.push_back(1); */
    /* a1.push_back(1,1); */
    a1.emplace_back(1,3);
    display(a1);

    a1.push_back(AA(1,1));
    display(a1);
    a1.emplace_back(AA(1,2));
    display(a1);
    
    a1.emplace_back(1,3);
    display(a1);
    //有毛病,也突然就编译好了
}
int main(void)
{
    test();
    return 0;
}
cpp 复制代码
Person(char* ,int)
Person(const Person &)
yueyue--101   

Person(char* ,int)
Person(const Person &)
Person(const Person &)
yueyue--101   kaixin--102   

Person(char* ,int)
Person(const Person &)
Person(const Person &)
yueyue--101   kaixin--102   jiajia--103   

AA(int ,int)
1--3   

AA(int ,int)
AA(const AA &&)
AA(const AA &)
1--3   1--1   

AA(int ,int)
AA(const AA &&)
AA(const AA &)
AA(const AA &)
1--3   1--1   1--2   

AA(int ,int)
1--3   1--1   1--2   1--3  

emplace_back(int,int)有用,怎么Person还更加鸡肋了

06_listspec_splice.cc

cpp 复制代码
#include <iostream>
#include <vector>
#include <deque>
#include <list>
using std::cout;
using std::endl;
using std::vector;
using std::list;
using std::deque;

template <typename Container>
void display(const Container & con){
    for(auto &ele: con){
        cout<<ele<<" ";
    }
    cout<<endl;
}

struct CompareList{
    bool operator()(const int &lhs,const int &rhs)const{
        cout<<"CompareList"<<endl;
        return lhs<rhs;
    }
};

//-------------------------------------//
void test(){
    list<int> num{1,6,3,3,3,2,3,4,5,0,2,7,6};
    display(num);

    cout<<endl<<"list unique"<<endl;
    num.unique();//只能去重连续重复元素
    display(num);//和sort配合

    cout<<endl<<"list reverse"<<endl;
    num.reverse();
    display(num);

    //-------------------------------------//
    cout<<endl<<"list sort: small-->big"<<endl;
    num.sort();
    num.unique();
    display(num);
    num.sort(std::less<int>());
    display(num);
    num.sort(std::greater<int>());
    display(num);
    num.sort(CompareList());//传一个对象
    display(num);


    //-------------------------------------//
    cout<<endl<<"list  merge"<<endl;
    list<int>other{89,4,76,23,767};
    other.sort();
    /* num.sort(std::greater<int>()); */
    /* other.sort(std::greater<int>()); */
    display(other);//需要顺序一致(必须是从小到大),最终结果才是有序的
    num.merge(other);
    display(num);
    /* display(other); */
    //-------------------------------------//
    cout<<endl<<"list  splice"<<endl;
    list<int>other1{1111,7777,5555};
    auto it=num.begin();
    it++;
    it++;
    cout<<*it<<endl;
    num.splice(it,other1);
    display(num);
}


//-------------------------------------//
void test0(){
    list<int> num{1,2,3,4,5,7};
    display(num);
    cout<<endl<<"list  splice"<<endl;
    list<int>other1{1111,7777,5555,6666,9999,3333};
    auto it=num.begin();
    it++;
    it++;
    cout<<*it<<endl;
    auto oit=other1.begin();
    oit++;
    oit++;
    cout<<*oit<<endl;
    num.splice(it,other1,oit);
    display(num);
}

//-------------------------------------//
void test1(){
    list<int> num{1,2,3,4,5,7};
    display(num);
    cout<<endl<<"list  splice"<<endl;
    list<int>other1{1111,7777,5555,6666,9999,3333};
    auto it=num.begin();
    it++;
    it++;
    cout<<*it<<endl;
    auto oit=other1.begin();
    oit++;
    oit++;
    auto oit1=other1.end();
    cout<<*oit<<endl;
    num.splice(it,other1,oit,oit1);
    display(num);
}

//-------------------------------------//
void test2(){
    list<int> num{1,2,3,4,5,7};
    cout<<endl<<"<<<<<<<<<<<<list  splice"<<endl;
    display(num);
    auto it=num.begin();
    auto it0=num.begin();
    auto it1=num.end();
    it++;
    it++;
    cout<<*it<<endl;
    /* num.splice(it0,num,it,it1);//再前面插入了一坨,后面的后移 */
    /* num.splice(it,num,it,it1); */
    //迭代器有交叉会出现美丽的格栅!!!!!!!
    display(num);

    num.splice(it,num,it);//没变化喵
    num.splice(num.begin(),num,it);//一小坨挤走了后面一大坨
                                   
    /* num.splice(it,num); */
    //迭代器有交叉会出现美丽的格栅!!!!!!!
    //double free 
    //double free 
    //double free 
    display(num);

    cout<<"xixi"<<endl;
    //哥们已经晕了,坏!!!
    //哥们已经晕了,坏!!!
    //哥们已经晕了,坏!!!
    //哥们已经晕了,坏!!!
}

int main(void)
{
    /* test(); */
    /* test0(); */
    /* test1(); */
    test2();
    return 0;
}

07_classstruct.cc

cpp 复制代码
#include <iostream>
using std::cout;
using std::endl;

//------------------------------------//
class Base{
public:
    void pp(){cout<<"Base::pp()"<<endl;}
};
class Derivd
:Base
{};
//------------------------------------//

struct Base1{
public:
    void pp1(){cout<<"Base::pp()"<<endl;}
};
struct Derivd1
:Base1
{};
//------------------------------------//


void test(){
    Derivd d1;
    /* d1.pp(); */
    Derivd1 d2;
    d2.pp1();
    //struct class 的区别
    //默认的成员权限,默认的继承方式
}

int main(void)
{
    test();
    return 0;
}

08_set.cc

cpp 复制代码
#include <iostream>
#include <vector>
#include <deque>
#include <string.h>
#include <random>
#include <set>
using std::cout;
using std::endl;
using std::vector;
using std::deque;
using std::ostream;
using std::set;
using std::pair;

template <typename Container>
void display(const Container & con){
    for(auto &ele: con){
        cout<<ele<<" ";
    }
    cout<<endl;
}

void test(){
    set<int>num{1,2,3,4,5,6,66,6,6,7,7,7};
    //存放key值,key is unique,small-->big
    display(num);
    set<int,std::greater<int>>num1{1,2,3,4,5,6,66,6,6,7,7,7};
    //函数参数里面,不传类型
    display(num1);
    
    //---------------------------------//
    // count find
    //---------------------------------//
    cout<<endl<<"set:count()"<<endl;
    size_t cnt=num.count(1);
    cout<<cnt<<endl;
    cout<<endl<<"set:find()"<<endl;
    auto it=num.find(1);
    /* cout<<*it<<endl; */
    if(it==num.end()){
        cout<<" no find this key "<<endl;
    }else{
        cout<<"find it  "<<*it<<endl;
    }


    //---------------------------------//
    // inserti(one , iterator,{})
    //---------------------------------//
    cout<<endl<<"set: pair?insert"<<endl;
    pair<set<int>::iterator,bool>ret=num.insert(6);
    if(ret.second){
        cout<<" fail to insert  "<<endl;
    }else{
        /* cout<<"OKOK,is  "<<ret.first<<endl; */
        cout<<"OKOK,is  "<<endl;
    }
    display(num);

    vector<int>v{2,3,4,2,4,55,77,45,2,1,1,1};
    num.insert(v.begin(),v.end());
    display(num);

    num.insert({66666,8888});
    display(num);


    //---------------------------------//
    //erase(pos,[pos,pos),)
    //---------------------------------//
    cout<<endl<<"set: erase"<<endl;
    num.erase(++num.begin());
    display(num);
}

int main(void)
{
    test();
    return 0;
}

09_setErase.cc

cpp 复制代码
#include <iostream>
#include <vector>
#include <deque>
#include <string.h>
#include <random>
#include <set>
using std::cout;
using std::endl;
using std::vector;
using std::deque;
using std::ostream;
using std::set;
using std::pair;

template <typename Container>
void display(const Container & con){
    for(auto &ele: con){
        cout<<ele<<" ";
    }
    cout<<endl;
}

void test(){
    set<int>num{1,2,3,4,5,6,66,6,6,7,7,7};
    display(num);

    //delete single_num
    for(auto it=num.begin();it!=num.end();++it){
        if(*it&1){
            num.erase(it++);
            //1
            /* auto temp=it; */
            /* it++; */
            /* num.erase(temp); */
            //删除的迭代器会失效,其他的不受影响(like array)
            //2
            /* it=num.erase(it); */
        }
    }
    display(num);
}

int main(void)
{
    test();
    return 0;
}

作业

01 STL中的容器包括哪些?各自具有哪些特点?

cpp 复制代码
STL(Standard Template Library)是 C++ 标准库的一部分,提供了一系列高效且灵活的容器和算法。STL 容器可以分为四大类:序列容器、关联容器、无序关联容器和容器适配器。下面是对这些容器及其特点的详细介绍:



1. 序列容器(Sequence Containers)
序列容器是按照特定顺序存储元素的容器。它们包括:

std::vector:

特点:动态数组,支持随机访问(常数时间复杂度),在尾部插入和删除元素效率高(常数时间复杂度)。中间插入或删除元素的效率较低(线性时间复杂度),因为可能需要移动元素。
用法:适用于需要频繁随机访问和尾部插入/删除操作的场景。
std::deque:

特点:双端队列,支持在两端高效地插入和删除元素(常数时间复杂度),随机访问的效率略低于 std::vector。
用法:适用于需要在两端频繁插入/删除的场景,同时也需要随机访问。
std::list:

特点:双向链表,支持在任意位置插入和删除元素的效率很高(常数时间复杂度),但不支持随机访问(访问时间复杂度为线性时间)。
用法:适用于需要频繁插入/删除操作且不需要随机访问的场景。
std::forward_list(C++11 引入):

特点:单向链表,支持高效的插入和删除操作,但只支持单向遍历,不支持随机访问。
用法:适用于需要内存开销更小且操作模式为单向遍历的场景。
std::array(C++11 引入):

特点:固定大小的数组,大小在编译时确定,支持随机访问,内存布局与传统数组相同。
用法:适用于大小固定且在编译时已知的场景。




2. 关联容器(Associative Containers)
关联容器通过特定的键值对来组织数据,自动按键排序。它们包括:

std::set:

特点:存储唯一的键值,按键的顺序自动排序,支持快速查找、插入和删除(对数时间复杂度)。
用法:适用于需要存储唯一元素并保持排序的场景。
std::multiset:

特点:与 std::set 相似,但允许存储重复的键值。
用法:适用于需要存储可能重复的元素并保持排序的场景。
std::map:

特点:存储键值对,键值对按键自动排序,键唯一,支持快速查找、插入和删除(对数时间复杂度)。
用法:适用于需要存储键值对且按键排序的场景。
std::multimap:

特点:与 std::map 相似,但允许键重复。
用法:适用于需要存储可能具有相同键的多个键值对并保持排序的场景。




3. 无序关联容器(Unordered Associative Containers)
无序关联容器基于哈希表实现,元素的存储顺序不确定。它们包括:

std::unordered_set:

特点:存储唯一的键值,通过哈希函数进行查找,平均时间复杂度为常数时间,但最坏情况下可能为线性时间。
用法:适用于需要快速查找、插入和删除唯一元素的场景,且不要求排序。
std::unordered_multiset:

特点:与 std::unordered_set 相似,但允许存储重复的键值。
用法:适用于需要存储可能重复的元素且不要求排序的场景。
std::unordered_map:

特点:存储键值对,通过哈希函数进行查找,键唯一,平均时间复杂度为常数时间,但最坏情况下可能为线性时间。
用法:适用于需要快速查找、插入和删除键值对且不要求排序的场景。
std::unordered_multimap:

特点:与 std::unordered_map 相似,但允许键重复。
用法:适用于需要存储可能具有相同键的多个键值对且不要求排序的场景。






4. 容器适配器(Container Adapters)
容器适配器提供了对其他容器的特定接口进行封装。它们包括:

std::stack:

特点:基于 std::deque 或 std::list 实现的栈,支持后进先出(LIFO)操作,提供 push、pop 和 top 操作。
用法:适用于需要栈结构的场景。
std::queue:

特点:基于 std::deque 实现的队列,支持先进先出(FIFO)操作,提供 push、pop 和 front 操作。
用法:适用于需要队列结构的场景。
std::priority_queue:

特点:基于 std::vector 实现的优先队列,支持按优先级排序的操作,提供 push、pop 和 top 操作。
用法:适用于需要按照优先级处理元素的场景。
这些容器类型提供了灵活的数据结构选择,可以根据具体需求选择最适合的容器。

02 题目:编写代码:将一个list中的char *指针元素赋值给一个vector中的string。

提示:加入list的定义如下,list<char*> lst= { "hello", "world", "!" };如何将list中的内容赋值给vector<string>

cpp 复制代码
#include <iostream>
#include <vector>
#include <deque>
#include <list>
#include <string>
using std::cout;
using std::endl;
using std::vector;
using std::deque;
using std::list;
using std::string;

template <typename Container>
void display(const Container & con){
    for(auto &ele: con){
        cout<<ele<<" ";
    }
    cout<<endl;
}

void test(){
    list<char*> l{"i ","love ","xixi"};
    //worning "i"=const char*
    vector<string> v(l.begin(),l.end());
    display(v);
}

int main(void)
{
    test();
    return 0;
}

03 编程题:从标准输入读取 string 序列,存入一个 deque 中。编写一个循环,用迭代器打印 deque 中的元素。

提示:熟悉deque的基本函数的使用方式。

cpp 复制代码
#include <iostream>
#include <vector>
#include <deque>
#include <list>
#include <string>
using std::cout;
using std::cin;
using std::endl;
using std::vector;
using std::deque;
using std::list;
using std::string;

template <typename Container>
void display(const Container & con){
    for(auto &ele: con){
        cout<<ele<<" ";
    }
    cout<<endl;
}

void test(){
    deque<string> v;
    string s1;
    while(true){
        getline(cin,s1);
        if(s1=="byby"){break;}
        v.push_back(s1);
    }
    for(deque<string>::iterator it=v.begin();it!=v.end();++it){
        cout<<*it<<endl;
    }
    display(v);
}

int main(void)
{
    test();
    return 0;
}
cpp 复制代码
#include<iostream>
#include<deque>
#include<string>

using namespace std;

int main()
{
	deque<string> dq;
	string word;
	while (cin >> word)
	{
		dq.push_back(word);
	}
	for (auto it = dq.cbegin(); si != dq.cend(); ++dq){
		cout << *it << endl;
	}

	return 0;
}

04 编程题:从一个 list 拷贝元素到两个 deque 中。值为偶数的所有元素都拷贝到一个 deque 中,而奇数值元素都拷贝到另一个 deque 中。

提示:熟悉list容器与deque容器的基本操作,包括初始化、遍历、插入等等

cpp 复制代码
#include <iostream>
#include <vector>
#include <deque>
#include <list>
#include <string>
using std::cout;
using std::cin;
using std::endl;
using std::vector;
using std::deque;
using std::list;
using std::string;

template <typename Container>
void display(const Container & con){
    for(auto &ele: con){
        cout<<ele<<" ";
    }
    cout<<endl;
}

void test(){
    list<int> l{0,1,2,3,4,5,6,7,8,9,10,11,12,134};
    deque<int> v1;
    deque<int> v2;
    for(auto it=l.begin();it!=l.end();++it){
        if(*it&1){
            v1.push_back(*it);
        }else{
            v2.push_back(*it);
        }
    }
    display(l);
    display(v1);
    display(v2);
}

int main(void)
{
    test();
    return 0;
}

05 题目:学生成绩管理系统

题目要求:

1 .制作一个学生成绩单管理系统

2 .将student自定义数据类型进行排序,student中属性有姓名、年龄、语文成绩,数学成绩,英语成绩

排序规则 :按照总成绩sum进行降序,如果总成绩sum相同按照语文成绩进行降序

提示:熟悉list容器的基本操作:包括初始化、遍历、排序等等

cpp 复制代码
#include <iostream>
#include <string.h>
#include <list>
using std::cout;
using std::endl;
using std::list;
using std::ostream;


template <typename Container>
void display(const Container & con){
    for(auto &ele: con){
        cout<<ele<<" ";
    }
    cout<<endl<<endl;
}

//-------------------------------------//
//-------------------------------------//
class Person{
public:
    Person(){}
    Person(const char* name="xixi",const int sc=0,
           const int chi=0,const int math=0,const int eng=0)
        :_name(new char[strlen(name)+1]())
         ,_age(sc),_chi(chi),_math(math),_eng(eng)
    {
        strcpy(_name,name);
        cout<<"Person(const char *,int*4)"<<endl;
    }


    Person(const Person & p)
        :_name(new char[strlen(p._name)+1]())
         ,_age(p._age),_chi(p._chi),_math(p._math),_eng(p._eng)
    {
        strcpy(_name,p._name);
        cout<<"Person(const Person &)"<<endl;
    }


    Person(Person && p)
        :_name(p._name)
         ,_age(p._age),_chi(p._chi),_math(p._math),_eng(p._eng)
    {
        p._name=nullptr;
        cout<<"Person(const Person &&)"<<endl;
    }


    ~Person(){
        if(_name){
            delete []  _name;
            _name=nullptr;
        }
    }


    Person & operator=(const Person & p){
        if(this!=&p){
            delete [] _name;
            _name=new char[strlen(p._name)+1]();
            strcpy(_name,p._name);
            _age=p._age;_chi=p._chi;_math=p._math;_eng=p._eng;
        }
        return *this;
    }


    int get_sco()const {
        return _chi+_math+_eng;
    }
    int get_chi()const{
        return _chi;
    }

    friend ostream & operator<<(ostream & os,const Person & p);
    //------------------------//

private:
    char* _name;
    int _age;
    int _chi;
    int _math;
    int _eng;
};


ostream & operator<<(ostream & os,const Person & p){
    os<<p._name<<"--"<<p._age<<"--"<<
        p._chi<<"--"<<p._math<<"--"<<p._eng<<"\t";
    os<<"sco: "<<p.get_sco()<<"\t"<<"chi: "<<p.get_chi()<<endl;
    return os;
}
//-------------------------//
//-------------------------//

struct CompareList{
    bool operator()(const Person & p1,const Person & p2){
        if(p1.get_sco()!=p2.get_sco()){
            return p1.get_sco()>p2.get_sco();
        }else{
            return p1.get_chi()>p2.get_chi();
        }
    }//不能加const,haohaohao,能加了
};

//-------------------------//
//-------------------------//
void test(){
    list<Person> l{{"xixi",28,89,90,100},
        {"jiajia",22,95,92,90},
        {"yueyue",22,95,91,91},
        {"kaixin",23,90,89,100},
        {"lili",35,90,90,95}};
    display(l);
    l.sort(CompareList());
    display(l);
}
int main(void)
{
    test();
    return 0;
}
cpp 复制代码
#include<iostream>
#include <list>
#include <string>

using namespace std;
class Student 
{
public:
    Student(string name, int ch, int ma,int e) 
    {
                m_Name = name;
		chinese = ch;
		math = ma;
		English = e;
		sum = ch + ma + e;
     }

public:
	string m_Name;  //姓名
	int chinese;   //语文成绩
	int math;   //数学成绩
	int English;//英语成绩
	int sum;//总成绩

};

bool ComparePerson(Student& p1, Student& p2)//定义sort排序从大到小
{
	if (p1.sum == p2.sum) 
    {
		return p1.sum < p2.sum;
	}
	else
	{
		return  p1.chinese < p2.chinese;
	}
}

void test() 
{

	list<Student> k;

	Student p1("杜雯菲", 88,77,95);
	Student p2("杜蚊分", 67,58,26);
	Student p3("李八八", 95,77,88);
	Student p4("赵二蛋",86,75,68);
	Student p5("王小牛", 86,46,86);
	Student p6("张小哈",89,57,68);

	k.push_back(p1);
	k.push_back(p2);
	k.push_back(p3);
	k.push_back(p4);
	k.push_back(p5);
	k.push_back(p6);

	for (list<Student>::iterator it = k.begin(); it != k.end(); it++) 
    {
		cout << "姓名: " << it->m_Name
            << " 语文: " << it->chinese
			<< " 数学: " << it->math 
            << " 英语: " << it->English
            << "  总成绩: " << it->sum
            <<  endl;
	}

	cout << "---------------------------------" << endl;
	k.sort(ComparePerson); //排序
	cout << "排序后" << endl;
	for (list<Student>::iterator it = k.begin(); it != k.end(); it++)
    {
		cout << "姓名: " << it->m_Name 
            << " 语文: " << it->chinese
			<< " 数学: " << it->math 
            << " 英语: " << it->English 
            << "  总成绩: " << it->sum << endl;
	}
}

int main() 
{
	test();
	return 0;
}
相关推荐
2301_801760933 分钟前
数据结构--PriorityQueue
数据结构
乐悠小码9 分钟前
数据结构------队列(Java语言描述)
java·开发语言·数据结构·链表·队列
ROC_bird..28 分钟前
STL - vector的使用和模拟实现
开发语言·c++
机器视觉知识推荐、就业指导28 分钟前
C++中的栈(Stack)和堆(Heap)
c++
Mr_Xuhhh3 小时前
递归搜索与回溯算法
c语言·开发语言·c++·算法·github
无敌岩雀3 小时前
C++设计模式行为模式———命令模式
c++·设计模式·命令模式
爱吃生蚝的于勒5 小时前
C语言内存函数
c语言·开发语言·数据结构·c++·学习·算法
小白学大数据7 小时前
Python爬虫开发中的分析与方案制定
开发语言·c++·爬虫·python
versatile_zpc9 小时前
C++初阶:类和对象(上)
开发语言·c++
小鱼仙官9 小时前
MFC IDC_STATIC控件嵌入一个DIALOG界面
c++·mfc