C++系列笔记(十)

简介: C++系列笔记(十)

   【导读】《21天学通C++》这本书通过大量精小短悍的程序详细而全面的阐述了C++的基本概念和技术,包括管理输入/输出、循环和数组、面向对象编程、模板、使用标准模板库以及创建C++应用程序等。这些内容被组织成结构合理、联系紧密的章节,每章都可在1小时内阅读完毕,都提供了示例程序清单,并辅以示例输出和代码分析,以阐述该章介绍的主题。本文是系列笔记的第十篇,欢迎各位阅读指正!            

对包含对象的list进行排序以及删除其中的元素


  如果list的元素类型为类,而不是int等简单内置类型,如何对其进行排序呢?假设有一个包含地址簿条目的list,其中每个元素都是一个对象,包含姓名、地址等内容,如何确保按姓名对其进行排序呢?答案是采取下面两种方式之一:

  • 在list包含的对象所属的类中,实现运算符<。
  • 提供一个排序二元谓词——一个这样的函数,即接受两个输入值,并返回一个布尔值,指出第一个值是否比第二个值小。典型代码:
#include<iostream>#include<algorithm>#include<string>#include<vector>#include<list>usingnamespacestd;
template<typenameT>voidDisplayContents(constT&Inputs)
{
for (autoiElements=Inputs.cbegin(); iElements!=Inputs.cend(); ++iElements)
cout<<*iElements<<endl;;
cout<<endl;
}structContactItem{
stringstrname;
stringstrphone;
stringstrdisplayrep;
ContactItem(conststring&strName, conststring&strPhone)
        {
strname=strName;
strphone=strPhone;
strdisplayrep= (strName+": "+strPhone);
        }
booloperator== (constContactItem&itemToCompare) const        {
return (itemToCompare.strname==this->strname);
        }
booloperator< (constContactItem&itemToCompare) const        {
return (this->strname<itemToCompare.strname);
        }
operatorconstchar*() const        {
returnstrdisplayrep.c_str();
        }
};
boolSortOnPhoneNumber(constContactItem&item1, constContactItem&item2)
{
return (item1.strphone<item2.strphone);
}
intmain()
{
list<ContactItem>Contacts;
Contacts.push_back(ContactItem("xiewenrui,", "+15797639728"));
Contacts.push_back(ContactItem("chenchuanxi", "+1234567"));
Contacts.push_back(ContactItem("hezhiqiang", "+1345678"));
cout<<"list in initial idea: "<<endl;
DisplayContents(Contacts);
Contacts.sort();
cout<<"order: "<<endl;
DisplayContents(Contacts);
Contacts.sort(SortOnPhoneNumber);
cout<<"after sort in phone number: "<<endl;
DisplayContents(Contacts);
}

输出为:

listininitialidea:
xiewenrui,: +15797639728chenchuanxi: +1234567hezhiqiang: +1345678order:
chenchuanxi: +1234567hezhiqiang: +1345678xiewenrui,: +15797639728aftersortinphonenumber:
chenchuanxi: +1234567hezhiqiang: +1345678xiewenrui,: +15797639728

C++11


  从C++11起,您可以使用forward_list,而不是双向链表std::list。std::forward_list是一种单向链表,即只允许沿一个方向遍历。要使用std::forward_list,需要包含头文件#include<forward_list> forward_list 的用法与 list 很像,但只能沿一个方向移动迭代器,且插入元素时只能使用函数push_front(),而不能使用push_back()。当然,总是可以使用insert()及其重载版本在指定位置插入元素。

forward_list的优点在于,它是一种单向链表,占用的内存比list稍少,因为只需指向下一个元素,而无需指向前一个元素。

STL集合类


  容器 set和 multiset让程序员能够在容器中快速查找键,键是存储在一维容器中的值。set和multiset之间的区别在于,后者可存储重复的值,而前者只能存储唯一的值。

要使用std::set或set::multiset类,需要包含头文件:位于set中特定位置的元素不能替换为值不同的新元素,这是因为set将把新元素同二叉树中的其他元素进行比较,进而将其放在其他位置。

STL set和multiset的基本操作


//实例化std::set<int>setIntegers;
std::multiset<int>msetIntegers;

要声明一个指向set或multiset的迭代器

std::set<int>::const_iteratoriElementInSet;
std::multiset<int>::const_iteratoriElementInMultiset;

如果需要一个可用于修改值或调用非const函数的迭代器,应将const_iterator替换为iterator。

鉴于set和multiset都是在插入时对元素进行排序的容器,如果您没有指定排序标准,它们将使用默认谓词std::less,确保包含的元素按升序排列。要创建二元排序谓词,可在类中定义一个operator(),让它接受两个参数(其类型与集合存储的数据类型相同),并根据排序标准返回true。下面是一个二元谓词,他按降序排序:

template<typenameT>structSortDescending{
booloperator() (constT&lhs,constT&rhs) const    {
return (lhs>rhs);
    }
};

然后实例化set或multiset时指定该谓词:

set<int, ortDescending<int>>setIntegers;
multiset<int,ortDescending<int>>msetIntegers;

在set和multiset插入元素


setIntegers.insert();

msetIntegers.insert()

multiset::count(value)它返回multiset中有多少个元素存储了指定的值。

在set和multiset中查找元素


诸如set、multiset、map和multimap等关联容器都提供了成员函数find(),它让您能够根据给定的键来查找值:

autoiElementsFound=setIntegers.find(-1);
if (iElementsFound!=setIntegers.end())
cout<<"Element"<<*iElementsFound<<""found"<<endl;elsecout<<"Elemenr not found in set!"<<endl;

删除set和multiset中的元素


诸如set、multiset、map和multimap等关联容器都提供了成员函数erase(),它让您能够根据键删除值:setObeject.erase(key); erase函数的另一个版本接受一个迭代器作为参数,并删除该迭代器指向的元素:setObeject.erase(iElement);

通过使用迭代器指定的边界,可将指定范围内的所有元素都从set或multiset中删除:setObeject.erase(iLowerBound,iUpperBound);

C++11


STL散列集合实现std::unordered_set和std::unordered_multiset。STL提供的容器类std::unordered_set就是基于散列的set。要使用STL容器std::unordered_set或std::unordered_multiset,需要包含头文件<unordered_set>:#include<unordered_set>相比于std::set,这个类的用法差别不大。然而,unordered_set的一个重要特征是,有一个负责确定排列顺序的散列函数:

unordered_set<int>::hasher HFn = usetInt.hash_function();

典型代码如下:

#include<iostream>#include<algorithm>#include<string>#include<vector>#include<unordered_set>usingnamespacestd;
template<typenameT>voidDisplayContents(constT&Inputs)
{
cout<<"number of elements,size()="<<Inputs.size()<<endl;
//最大桶数cout<<"Max bucket count="<<Inputs.max_bucket_count() <<endl;
//负载系数cout<<"Load factor= "<<Inputs.load_factor() <<endl;
//最大负载系数cout<<"mx_load_factor= "<<Inputs.max_load_factor() <<endl;
cout<<"unordered set contains:"<<endl;
for (autoiElements=Inputs.cbegin(); iElements!=Inputs.cend(); ++iElements)
cout<<*iElements<<endl;;
cout<<endl;
}
intmain()
{
unordered_set<int>usetInt;
usetInt.insert(1000);
usetInt.insert(-3);
usetInt.insert(2011);
usetInt.insert(100);
DisplayContents(usetInt);
usetInt.insert(999);
DisplayContents(usetInt);
return0;
}

输出为:

numberofelements,size()=4Maxbucketcount=536870911Loadfactor=0.5mx_load_factor=1unorderedsetcontains:
1000-32011100numberofelements,size()=5Maxbucketcount=536870911Loadfactor=0.625mx_load_factor=1unorderedsetcontains:
1000-39992011100
相关文章
|
6月前
|
算法 C++
算法笔记:递归(c++实现)
算法笔记:递归(c++实现)
|
6月前
|
编译器 C++
《Effective C++ 改善程序与设计的55个具体做法》 第一章 笔记
《Effective C++ 改善程序与设计的55个具体做法》 第一章 笔记
|
4月前
|
C++ 容器
【C/C++笔记】迭代器
【C/C++笔记】迭代器
28 1
|
4月前
|
存储 安全 程序员
【C/C++笔记】迭代器范围
【C/C++笔记】迭代器范围
73 0
|
5月前
|
C++ Windows
FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg
在Windows上使用Visual Studio 2022进行FFmpeg和SDL2集成开发,首先安装FFmpeg至E:\msys64\usr\local\ffmpeg,然后新建C++控制台项目。在项目属性中,添加FFmpeg和SDL2的头文件及库文件目录。接着配置链接器的附加依赖项,包括多个FFmpeg及SDL2的lib文件。在代码中引入FFmpeg的`av_log`函数输出"Hello World",编译并运行,若看到"Hello World",即表示集成成功。详细步骤可参考《FFmpeg开发实战:从零基础到短视频上线》。
220 0
FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg
|
7月前
|
存储 C++ 容器
黑马c++ STL部分 笔记(7) list容器
黑马c++ STL部分 笔记(7) list容器
|
7月前
|
算法 C++ 容器
黑马c++ STL常用算法 笔记(5) 常用算术生成算法
黑马c++ STL常用算法 笔记(5) 常用算术生成算法
|
7月前
|
算法 C++ 容器
黑马c++ STL常用算法 笔记(4) 常用拷贝和替换算法
黑马c++ STL常用算法 笔记(4) 常用拷贝和替换算法
|
7月前
|
存储 算法 搜索推荐
黑马c++ STL常用算法 笔记(3) 排序算法
黑马c++ STL常用算法 笔记(3) 排序算法
|
7月前
|
算法 C++
黑马c++ STL常用算法 笔记(2) 查找算法
黑马c++ STL常用算法 笔记(2) 查找算法