C++STL应用


容器与迭代器的结合

迭代器是一种可以遍历容器元素的数据类型。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介,C++梗趋向于用迭代器而不是数组下标操作,因为标准库为每一种标准容器定义了一种迭代器类型,而只有少数容器支持数组下标操作访问容器元素。可以通过迭代器指向你想访问容器的元素地址。

vector,是数组实现,也就是说,只要知道了数组的首地址,就能访问到后面的元素。

我们可以通过将数组的下标传入函数来实现取值或是对数组元素的操作。也可以通过vector迭代器来实现。例如,在transInvT中,我们通过将传入的参数添加输出容器和函数(或对象)来实现容器与迭代器的结合。

cstl.h

#ifndef CSTL_H
#define CSTL_H

#include <iostream>

void Test();

#endif // CSTL_H

cstlcpp

#include "cstl.h"
#include <vector>
#include <map>
#include <iostream>
#include <algorithm>
#include <functional>
#include <set>
using namespace std;

//对数组中的前nNum个元素取反
void transInv(int a[], int b[], int nNum) {
    for (int i = 0; i < nNum; i++)
    {
        b[i] = -a[i];
    }
}
//对数组中的前nNum个元素求平方
void transSqr(int a[], int b[], int nNum)
{
    for (int i = 0; i < nNum; i++)
    {
        b[i] = a[i] * a[i];
    }
}
//对数组取反的函数模板
template < typename T>
void transInvT(T a[], T b[], int nNum)
{
    for (int i = 0; i < nNum; i++)
    {
        b[i] = -a[i];
    }
}
template < typename T>
// 返回相反数
T InvT(T a)
{
    return -a;
}
template < typename T>
class MyThreshold {
public:
    MyThreshold(int n = 128) : _nThreshold(n) {}
    int operator()(T val)
    {
        return val < _nThreshold ? 0 : 1;
    }
    int _nThreshold;

};
//
template <typename inputIter, typename outputIter, typename MyOperator>
void transInvT(inputIter begInput, inputIter endInput,
    outputIter begOutPut, MyOperator op) {
    for (; begInput != endInput; begInput++, begOutPut++)
    {
//         *begOutPut = - (*begInput);
        *begOutPut = op(*begInput);


    }

}

//遍历数组的函数模板
template < typename T>
void outputCont(string strNme, ostream& os, T begin, T end)
{
    os << "数组"+strNme+"的遍历结果为:[";
    for (; begin != end; begin++)
    {
        os << *begin << " ";
    }
    os << "]" << endl;
}

void Test()
{
    //TestMap();
    //TestSet();
    //TestVector();

    const int N = 5;
    int a[N] = {1,2,4,3,5};
    //遍历数组
    outputCont("a", cout, a, a + N);

    //临时数组
    int b[N];
    //Vector(向量)是一个封装了动态大小数组的顺序容器(Sequence Container),跟任意其它类型容器一样,
    //它能够存放各种类型的数据。可以简单的认为,向量是一个能够存放任意类型的动态数组
    vector<double> vb(N);
    vector<double> vc(N);
    //对数组中的元素取反
    transInv(a, b, N);
    outputCont("Inv a取反", cout, b, b + N);
    //对数组中的元素取求平方
    transSqr(a, b, N);
    outputCont("Sqr a平方", cout, b, b + N);
    //对数组元素取反(使用模板)
    transInvT(a, b, N);
    outputCont("Inv a T模板取反", cout, b, b + N);

//    transInvT(a, a + N, b, InvT<int>);
    transInvT(a, a + N, vb.begin(), InvT<int>);
    outputCont("Inv a by iter迭代取反", cout, vb.begin(), vb.end());

    transInvT(a, a + N, vb.begin(), MyThreshold<int>(2));
    outputCont("Inv a by treshold二值化", cout, vb.begin(), vb.end());

    sort(a, a + N, mycomp<int>);
    sort(a, a + N, greater<int>());
    sort(a, a + N, MyCompC<int>());
    outputCont("a sorted排序", cout, a, a + N);
    vb.swap(vc);

}

在这里插入图片描述


学生信息操作(set)

添加:push_back()方法或者insert()方法都可以实现。
删除:erase()方法实现。
查找:find()方法实现,在查找的时候,单纯用find()并不会显示是否查找成功了,所以我们可以采用iterator一个iter来接受find()返回的下标,判断下标是否越界来输出查找的结果。
修改:set是由const修饰的,不可修改,但可以先删除后增加来达到修改效果。

cstl.h

#ifndef CSTL_H
#define CSTL_H

#include <iostream>

void TestSet();

#endif // CSTL_H

cstl.cpp

class studentInfo {
public:
    studentInfo(string strNo, string strName) {
        _strNo = strNo;
        _strName = strName;
    }
    string _strNo;
    string _strName;
    friend ostream& operator<<(ostream& os, const studentInfo& info)
    {
        os << info._strNo << " " << info._strName;
        return os;
    }
    friend bool operator<(const studentInfo& info1, const studentInfo& info2) {
        return info1._strNo < info2._strNo;

    }

};


void TestSet()
{
    vector<studentInfo> students;
    students.push_back(studentInfo("10021", "Zhang san"));      // 在vector最后添加一个元素
    students.push_back(studentInfo("10002", "Li si"));
    students.push_back(studentInfo("10003", "Wang wu"));
    students.push_back(studentInfo("10011", "Wang Liu"));
    students.push_back(studentInfo("10010", "Wu Liu"));
    set<studentInfo> studentSet(students.begin(), students.end());      // 定义studentSet为students的头部到尾部
    outputCont("student set", cout, studentSet.begin(), studentSet.end());
    
    studentSet.insert(studentInfo("10000","qkl"));	//增加元素
    outputCont("增加后student set", cout, studentSet.begin(), studentSet.end());
    
    set<studentInfo>::iterator iter;    // 定义迭代下标来判别是否查找成功
    iter=studentSet.find(studentInfo("10011","Li si"));      // 查找
    if(iter!=studentSet.end())
    {
        cout<<*iter<<endl;
    }
    else
    {
        cout<<"can not find "<<endl;
    }
    
    // set的元素是const修饰的,不可修改,需要修改的话可以先删除后添加
    
    studentSet.erase(studentInfo("10021","Zhang san"));     // 删除
    
    outputCont("student set", cout, studentSet.begin(), studentSet.end());
}

在这里插入图片描述


字符串运用(map)

增加:数组式地添加方法,key+value。
删除:通过iterator一个iter和++的特性来遍历容器中的key,当然也可以遍历value,找到后删除,未找到继续找,知道end()。
查找:iter遍历key或value来查找。
修改:通过key修改value最直接。
输入字符串并计算其出现次数:map一个容器,从begin到end,如果没有该字符,则创建并赋值为1;如果有且为到达字符结尾,则+1。最后再map一个迭代下标来挨个输出。
cstl.h

#ifndef CSTL_H
#define CSTL_H

#include <iostream>
void TestMap();
#endif // CSTL_H

cstl.cpp

#include "cstl.h"
#include <vector>
#include <map>
#include <iostream>
#include <algorithm>
#include <functional>
#include <set>
using namespace std;

void TestMap()
{
    map<string, int> stu;
    stu["01"] = 100;
    stu["10"] = 99;

    stu["05"] = 98;
    stu["10"] = 95;

    for (map<string, int>::iterator it = stu.begin(); it != stu.end(); it++)
    {
        cout << it->first << " " << it->second << endl;
    }

    map<string,int>::iterator iter=stu.begin();
    while(iter!=stu.end())      // 删除key为01的数据
    {
        if(iter->first=="01"){
            stu.erase(iter++);
            cout<<"delete succesful"<<endl;
        }
        else
            iter++;
    }

    iter=stu.begin();
    while(iter!=stu.end())      // 查找key为10的数据
    {
        if(iter->first=="10")
        {
            cout<<"find it"<<endl;
            cout<<iter->first<<" "<<iter->second<<endl;
            iter++;
        }
        else
            iter++;
    }
    if (iter!=stu.end())
    {
        cout<<"can not find "<<endl;
    }

    // map的key元素不可修改,value可以修改
    stu["05"]=198;
    cout<<"final"<<endl;
    for (map<string, int>::iterator it = stu.begin(); it != stu.end(); it++)
    {

        cout << it->first << " " << it->second << endl;
    }

    string str;
    cout<<"please input str"<<endl;
    cin>>str;
    int len=str.length();
    map<char,int> counterMap;   // 定义map容器存储字符及其出现次数
    for(int i=0;i<len;i++)
    {
        auto iter=counterMap.find(str[i]);
        if(iter!=counterMap.end())      // 有该字符且没有到达字符结尾,+1
        {
            ((*iter).second)++;
        }
        else        // 没有则添加
        {
            counterMap.insert(pair<char,int>(str[i],1));
        }
    }

    map<char,int>::iterator iterOt=counterMap.begin();      // 定义迭代下标来挨个输出
    for(;iterOt!=counterMap.end();iterOt++)
    {
        cout<<(*iterOt).first<<" "<<(*iterOt).second<<endl;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值