STL 中 List 学习

转载 2007年10月09日 21:07:00

使用STL通用算法find()在list中查找对象

我们如何在list中查找东西呢?STL的通用算法find()和find_if()可以做这些。 就象for_each(), count(), count_if() 一样,这些算法也使用iterator范围,这个范围指出一个list或任意 其他容器中的一部分来处理。通常首iterator指着开始的位置,次iterator指着停止处理的地方。 由次iterator指出的元素不被处理。

这是find()如何工作:

/*
|| How to find things in an STL list
*/
#include <string>
#include <list>
#include <algorithm>
#
int main (void) {
  list<string> Fruit;
  list<string>::iterator FruitIterator;
#
  Fruit.push_back("Apple");
  Fruit.push_back("Pineapple");
  Fruit.push_back("Star Apple");
#
  FruitIterator = find (Fruit.begin(), Fruit.end(), "Pineapple");
#
  if (FruitIterator == Fruit.end()) {
    cout << "Fruit not found in list" << endl;
  }
  else {
   cout << *FruitIterator << endl;
  }
}

输出是:

Pineapple

如果没有找到指出的对象,就会返回Fruit.end()的值,要是找到了就返回一个指着找到的对象的iterator

--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
使用STL通用算法find_if()在list中搜索对象
    这是find()的一个更强大的版本。这个例子演示了find_if(),它接收一个函数对象的参数作为参数, 并使用它来做更复杂的评价对象是否和给出的查找条件相付。

    假设我们的list中有一些按年代排列的包含了事件和日期的记录。我们希望找出发生在1997年的事件。

 
/*
|| How to find things in an STL list MkII
*/
#include <string>
#include <list>
#include <algorithm>
#
class EventIsIn1997 {
public:
 bool operator () (string& EventRecord) {
   // year field is at position 12 for 4 characters in EventRecord     
   return EventRecord.substr(12,4)=="1997";
  } 
};
#
int main (void) {
  list<string> Events;
#
// string positions 0123456789012345678901234567890123456789012345     
  Events.push_back("07 January  1995  Draft plan of house prepared");
  Events.push_back("07 February 1996  Detailed plan of house prepared");
  Events.push_back("10 January  1997  Client agrees to job");
  Events.push_back("15 January  1997  Builder starts work on bedroom");
  Events.push_back("30 April    1997  Builder finishes work");
 #
  list<string>::iterator EventIterator =
      find_if (Events.begin(), Events.end(), EventIsIn1997());
#
  // find_if completes the first time EventIsIn1997()() returns true
  // for any object. It returns an iterator to that object which we
  // can dereference to get the object, or if EventIsIn1997()() never
  // returned true, find_if returns end()
  if (EventIterator==Events.end()) { 
    cout << "Event not found in list" << endl;
  }
  else {
   cout << *EventIterator << endl;
  }
}

这是程序的输出: 
10 January  1997  Client agrees to job
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
使用STL通用算法search在list中找一个序列
STL通用算法search()用来搜索一个容器,但是是搜索一个元素串,不象find()和find_if() 只搜索单个的元素
/*
|| How to use the search algorithm in an STL list
*/
#include <string>
#include <list>
#include <algorithm>
#
int main ( void ) {
#
  list<char> TargetCharacters;
  list<char> ListOfCharacters;
#
  TargetCharacters.push_back('/0');
  TargetCharacters.push_back('/0');
#
  ListOfCharacters.push_back('1');
  ListOfCharacters.push_back('2');
  ListOfCharacters.push_back('/0');
  ListOfCharacters.push_back('/0');
#
  list<char>::iterator PositionOfNulls =
    search(ListOfCharacters.begin(), ListOfCharacters.end(),
            TargetCharacters.begin(), TargetCharacters.end());
#
  if (PositionOfNulls!=ListOfCharacters.end())
    cout << "We found the nulls" << endl;
}

 如果TargetCharacters被发现,search就会返回一个指着ListOfCharacters中序列匹配的第一个 字符的iterator。如果没有找到匹配项,search返回ListOfCharacters.end()的值。

--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
使用list的成员函数sort()排序一个list
   要排序一个list,我们要用list的成员函数sort(),而不是通用算法sort()。所有我们用过的算法都是 通用算法。然而,在STL中有时容器支持它自己对一个特殊算法的实现,这通常是为了提高性能。

    在这个例子中,list容器有它自己的sort算法,这是因为通用算法仅能为那些提供随机存取里面元素 的容器排序,而由于list是作为一个连接的链表实现的,它不支持对它里面的元素随机存取。所以就需要一个特殊的 sort()成员函数来排序list。

    由于各种各样的原因,容器会提供特别的附加函数,或是因为效率的需要,或是因为利用容器结构的一些特性能够获得不同寻常的性能。

 
/*
|| How to sort an STL list
*/
#include <string>
#include <list>
#include <algorithm>
#
PrintIt (string& StringToPrint) { cout << StringToPrint << endl;}
#
int main (void) {
  list<string> Staff;
  list<string>::iterator PeopleIterator;
#
  Staff.push_back("John");
  Staff.push_back("Bill");
  Staff.push_back("Tony");
  Staff.push_back("Fidel");
  Staff.push_back("Nelson");
#
  cout << "The unsorted list " << endl;
  for_each(Staff.begin(), Staff.end(), PrintIt );
#
  Staff.sort();
#
  cout << "The sorted list " << endl;
  for_each(Staff.begin(), Staff.end(), PrintIt);
}

--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
用list的成员函数插入元素到list中

    list的成员函数push_front()和push_back()分别把元素加入到list的前面和后面。你可以使用insert() 把对象插入到list中的任何地方。
    insert()可以加入一个对象,一个对象的若干份拷贝,或者一个范围以内的对象。这里是一些 插入对象到list中的例子:
/*
|| Using insert to insert elements into a list.
*/
#include <list>
#include <iostream>
#include <algorithm>
using namespace std;
void PrintIt(int & x)
{
 cout<<x<<endl;
}
#
int main (void) {
 list<int> list1;
#
 /*
 || Put integers 0 to 9 in the list
 */
 for (int i = 0; i < 10; ++i)  list1.push_back(i);  
#
 /*
 || Insert -1 using the insert member function
 || Our list will contain -1,0,1,2,3,4,5,6,7,8,9
 */
 list1.insert(list1.begin(), -1);
#
 /*
 || Insert an element at the end using insert
 || Our list will contain -1,0,1,2,3,4,5,6,7,8,9,10
 */
 list1.insert(list1.end(), 10);
#
 /*
 || Inserting a range from another container
 || Our list will contain -1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,25,35
 */
 int IntArray[5] = {11,12,13,25,35};
 list1.insert(list1.end(), &IntArray[0], &IntArray[5]);
#
 /*
 || As an exercise put the code in here to print the lists!
 || Hint: use PrintIt and accept an interger
 */
 for_each(list1.begin(),list1.end(),PrintIt);
 return 0;
}


--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
List 构造函数

我们已经象这样定义了list:

  list<int> Fred;
你也可以象这样定义一个list,并同时初始化它的元素:   // define a list of 10 elements and initialise them all to 0
  list<int> Fred(10, 0);
  // list now contains 0,0,0,0,0,0,0,0,0,0
或者你可以定义一个list并用另一个STL容器的一个范围来初始化它,这个STL容器不一定是一个list, 仅仅需要是元素类型相同的的容器就可以。 
  vector<int> Harry;
  Harry.push_back(1);
  Harry.push_back(2);
#
  // define a list and initialise it with the elements in Harry
  list<int> Bill(Harry.begin(), Harry.end());
  // Bill now contains 1,2
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
使用list成员函数从list中删除元素
    list成员函数pop_front()删掉list中的第一个元素,pop_back()删掉最后一个元素。 函数erase()删掉由一个iterator指出的元素。还有另一个erase()函数可以删掉一个范围的元素。

 /*
|| Erasing objects from a list
*/
#include <list>
#
int main (void) {
  list<int> list1;   // define a list of integers
#
  /*
  || Put some numbers in the list
  || It now contains 0,1,2,3,4,5,6,7,8,9
  */
  for (int i = 0; i < 10; ++i)  list1.push_back(i);
#
  list1.pop_front();    // erase the first element 0
#
  list1.pop_back();     // erase the last element 9
 #
  list1.erase(list1.begin());  // erase the first element (1) using an iterator
#
  list1.erase(list1.begin(), list1.end());  // erase all the remaining elements
#
  cout << "list contains " << list1.size() << " elements" << endl;
}

输出是: list contains 0 elements
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
用list成员函数remove()从list中删除元素。

list的成员函数remove()用来从list中删除元素。 
/*
|| Using the list member function remove to remove elements
*/
#include <string>
#include <list>
#include <algorithm>
#
PrintIt (const string& StringToPrint) {
  cout << StringToPrint << endl;
}
#
int main (void) {
  list<string> Birds;
#
  Birds.push_back("cockatoo");
  Birds.push_back("galah");
  Birds.push_back("cockatoo");
  Birds.push_back("rosella");
  Birds.push_back("corella");
#
  cout << "Original list with cockatoos" << endl;
  for_each(Birds.begin(), Birds.end(), PrintIt);
 #
  Birds.remove("cockatoo");
#
  cout << "Now no cockatoos" << endl;
  for_each(Birds.begin(), Birds.end(), PrintIt);
 
}

输出是: 
Original list with cockatoos
cockatoo
galah
cockatoo
rosella
corella
Now no cockatoos
galah
rosella
corella

使用STL通用算法remove()从list中删除元素
通用算法remove()使用和list的成员函数不同的方式工作。一般情况下不改变容器的大小。 
/*
|| Using the generic remove algorithm to remove list elements
*/
#include <string>
#include <list>
#include <algorithm>
#
PrintIt(string& AString) { cout << AString << endl; }
#
int main (void) {
  list<string> Birds;
  list<string>::iterator NewEnd;
#
  Birds.push_back("cockatoo");
  Birds.push_back("galah");
  Birds.push_back("cockatoo");
  Birds.push_back("rosella");
  Birds.push_back("king parrot");
#
  cout << "Original list" << endl;
  for_each(Birds.begin(), Birds.end(), PrintIt);
#
  NewEnd = remove(Birds.begin(), Birds.end(), "cockatoo");
#
  cout << endl << "List according to new past the end iterator" << endl;
  for_each(Birds.begin(), NewEnd, PrintIt);
#
  cout << endl << "Original list now. Care required!" << endl;
  for_each(Birds.begin(), Birds.end(), PrintIt);
}
The output will be Original list
cockatoo
galah
cockatoo
rosella
king parrot
 
List according to new past the end iterator
galah
rosella
king parrot
 
Original list now. Care required!
galah
rosella
king parrot
rosella
king parrot
    通用remove()算法返回一个指向新的list的结尾的iterator。从开始到这个新的结尾(不含新结尾元素)的范围 包含了remove后剩下所有元素。你可以用list成员函数erase函数来删除从新结尾到老结尾的部分。
 

STL之四:list用法详解

list容器介绍 相对于vector容器的连续线性空间,list是一个双向链表,它有一个重要性质:插入操作和删除操作都不会造成原有的list迭代器失效,每次插入或删除一个元素就配置或释放一个元素空间...
  • longshengguoji
  • longshengguoji
  • 2013年01月19日 22:06
  • 19090

带你深入理解STL之List容器

上一篇博客中介绍的vector和数组类似,它拥有一段连续的内存空间,并且起始地址不变,很好的支持了随机存取,但由于是连续空间,所以在中间进行插入、删除等操作时都造成了内存块的拷贝和移动,另外在内存空间...
  • terence1212
  • terence1212
  • 2016年08月24日 17:29
  • 2597

STL中list详解

std::list Lists are sequence containers that allow constant time insert and erase operations anywh...
  • axiqia
  • axiqia
  • 2016年01月13日 22:23
  • 1120

STL之list函数详解

本文主要介绍了list的内部结构,list特殊的能力,以及list所支持操作函数,并在最终给出list应用实例。...
  • xiao3404
  • xiao3404
  • 2016年05月05日 22:18
  • 2054

C++ STL list介绍与使用方法

list(链表)链表也即链式表,在数据结构中,我们知道线性表的物理存储结构有两种,顺序表(数组)和链式表(结点)。链表是在堆中为每一个元素分配内存,然后利用指针将所有元素串起来。根据这种物理存储结构,...
  • Cypress1010
  • Cypress1010
  • 2016年12月15日 13:34
  • 1629

STL list链表的用法详细解析

原文地址:http://www.jb51.net/article/41525.htm 本文以List容器为例子,介绍了STL的基本内容,从容器到迭代器,再到普通函数,而且例子丰富,通俗易懂。不失为S...
  • Double2hao
  • Double2hao
  • 2016年03月01日 08:05
  • 2963

C++ STL源码学习(list篇)

C++ list源代码学习整理。
  • u011907342
  • u011907342
  • 2014年09月28日 18:25
  • 1054

STL源码:list

相较于vector的连续线性空间,list就显得复杂许多,它的好处是每次插入或删除一个元素,就配置或释放一个元素空间。因此,list对于空间的运用有绝对的精准,一点也不浪费。而且,对于任何位置的元素插...
  • u013074465
  • u013074465
  • 2015年03月24日 14:42
  • 1509

坑爹的stl list 的size()成员函数

刚做hihocoder #1086 Browser Caching的题,一开始的做法是stl unorderd_map+list,满心以为一次就AC,结果……TLE了。O(N)也能TLE!!(╯‵□′...
  • lyingson
  • lyingson
  • 2015年09月15日 14:17
  • 1184

【STL】list的常用方法

List的常用方法展示 【1】怎么赋值 【2】insert 【3】front、 back、 pop_back、 pop_front 【4】遍历、反序遍历 【5】排序sort 【6】swap 【7】un...
  • qq_31839479
  • qq_31839479
  • 2016年08月26日 11:21
  • 861
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:STL 中 List 学习
举报原因:
原因补充:

(最多只允许输入30个字)