Thinking in C++第二卷笔记之STL容器部分(二)

Thinking in C++第二卷笔记之STL容器部分(二)

相关日志

STL的总结

http://blog.163.com/zhoumhan_0351/blog/static/3995422720103174417603/

标准模板类(STL)(四),容器的比较、对比和总结

http://blog.163.com/zhoumhan_0351/blog/static/3995422720102267442299/

标准模板类(STL)(五),算法和函数

http://blog.163.com/zhoumhan_0351/blog/static/39954227201022783524890/

1、list

以一个双向链表数据结构来实现。可以在任何地方快速地插入或删除数据,而对于vectoris,deque而言这个操作是很高的代价的。但是如果想查找对象要频繁的遍历序列,最好不要用list。在元素被添加到list后,迭代器不会失效。通用的sort(),reverse()算法仅适用于数据,vector,deque。

If you have large, complex objects, you might want to choose a list first, 

especially if construction, destruction, copy-construction, and assignment are 

expensive and if you are doing things like sorting the objects or otherwise 

reordering them a lot。

2、集合set

仅接受每个元素的一个副本。

int isalpha(int ch)//测试参数是否为大、小写字母

template<class E>

    bool isalpha(E c, const locale& loc) const;

int isspace(int ch)//测试参数是否是空格、制表符或换行符

template<class E>

bool isspace(E c, const locale& loc) const;

template<class E, class T, class A>

    basic_istream<E, T>& getline(

        basic_istream <E, T>& is,

        basic_string<E, T, A>& str);

The first template function returns getline(is, str, is.widen('\n')).If the 

function extracts no elements, it calls setstate(failbit). In any case, it returns 

*this.和流操作运算符operator>>一样。如果没有遇到物理错误,文件结束,或非法字符, ios_base::operator void*( )调用good()来返回结果。

template<class E, class T, class A>

    basic_istream<E, T>& getline(

        basic_istream <E, T>& is,

        basic_string<E, T, A>& str,

        E delim);

例1:提取合法单词

//: C07:WordList.cpp

// Display a list of words used in a document.

#include <algorithm>

#include <cctype>

#include <cstring>

#include <fstream>

#include <iostream>

#include <iterator>

#include <set>

#include <sstream>

#include <string>

using namespace std;

char replaceJunk(char c) {

  // Only keep alphas, space (as a delimiter), and '

  return (isalpha(c) || c == '\'') ? c : ' ';

}

int main() {

  char* fname = "C:\\copy.txt";

  ifstream in(fname);

  set<string> wordlist;

  string line;

  while(getline(in, line)) {

    transform(line.begin(), line.end(), line.begin(),replaceJunk);

    istringstream is(line);

    string word;

    while(is>>word)

 {

  wordlist.insert(word);//以空格分开,但是要注意,并不是优先以空格为界定符,而是以数据类型

 }

  }

  // Output results:

  copy(wordlist.begin(),wordlist.end(),

       ostream_iterator<string>(cout, "\n"));

} ///:~

如下程序为使用输入输出流缓冲迭代器实现:

#include <cstring>

#include <fstream>

#include <iostream>

#include <iterator>

#include <set>

#include <string>

using namespace std;

int main() {

  char* fname = "copy.txt";

  ifstream in(fname);

  istreambuf_iterator<char> p(in), end;//默认构造函数创建的对象为指向流结束位置的,也就是超越末尾的迭代器对象。

  set<string> wordlist;

  while(p != end) {

    string word;

    insert_iterator<string> ii(word, word.begin());

    // Find the first alpha character:

    while(p != end && !isalpha(*p))

      ++p;

    // Copy until the first non-alpha character:

    while(p != end && isalpha(*p))

      *ii++ = *p++;

    if(word.size() != 0)

      wordlist.insert(word);

  }

  // Output results:

  copy(wordlist.begin(), wordlist.end(),

    ostream_iterator<string>(cout, "\n"));

} ///:~

template<class E, class T = char_traits<E> >

    class istreambuf_iterator

        : public iterator<input_iterator_tag, T, Dist> 

istreambuf_iterator(streambuf_type *sb = 0) throw();

istreambuf_iterator(istream_type& is) throw();

The first constructor initializes the input stream-buffer pointer with sb. The 

second constructor initializes the input stream-buffer pointer with is.rdbuf().

4、队列

是一个受到限制的deque形式。只可在一端放,另一端删除。我们用一个“银行出纳员”问题来模拟这个容器的应用。

// Using a queue and simulated multithreading

// to model a bank teller system.

#include <cstdlib>

#include <ctime>

#include <iostream>

#include <iterator>

#include <list>

#include <queue>

using namespace std;

class Customer {

  int serviceTime;

public:

  Customer() : serviceTime(0) {}

  Customer(int tm) : serviceTime(tm) {}

  int getTime() { return serviceTime; }

  void setTime(int newtime) { serviceTime = newtime; }

  friend ostream&

  operator<<(ostream& os, const Customer& c) {

    return os << '[' << c.serviceTime << ']';

  }

};

class Teller {

  queue<Customer>& customers;

  Customer current;

  enum { SLICE = 5 };

  int ttime; // Time left in slice

  bool busy; // Is teller serving a customer?

public:

  Teller(queue<Customer>& cq)

  : customers(cq), ttime(0), busy(false) {}

  Teller& operator=(const Teller& rv) {

    customers = rv.customers;

    current = rv.current;

    ttime = rv.ttime;

    busy = rv.busy;

    return *this;

  }

  bool isBusy() { return busy; }

  void run(bool recursion = false) {

    if(!recursion)

      ttime = SLICE;

    int servtime = current.getTime();

    if(servtime > ttime) {

      servtime -= ttime;

      current.setTime(servtime);

      busy = true; // Still working on current

      return;

    }

    if(servtime < ttime) {

      ttime -= servtime;

      if(!customers.empty()) {

        current = customers.front();

        customers.pop(); // Remove it

        busy = true;

        run(true); // Recurse

      }

      return;

    }

    if(servtime == ttime) {

      // Done with current, set to empty:

      current = Customer(0);

      busy = false;

      return; // No more time in this slice

    }

  }

};

// Inherit to access protected implementation:

class CustomerQ : public queue<Customer> {

public:

  friend ostream&

  operator<<(ostream& os, const CustomerQ& cd) {

    copy(cd.c.begin(), cd.c.end(),

      ostream_iterator<Customer>(os, " "));

    return os;

  }

};

int main() {

  CustomerQ customers;

  list<Teller> tellers;

  typedef list<Teller>::iterator TellIt;

  tellers.push_back(Teller(customers));

  srand(time(0)); // Seed the random number generator

  clock_t ticks = clock();

  // Run simulation for at least 5 seconds:

  while(clock() < ticks + 5 * CLOCKS_PER_SEC) {

    // Add a random number of customers to the

    // queue, with random service times:

    for(int i = 0; i < rand() % 5; i++)

      customers.push(Customer(rand() % 15 + 1));

    cout << '{' << tellers.size() << '}'

         << customers << endl;

    // Have the tellers service the queue:

    for(TellIt i = tellers.begin();i != tellers.end(); i++)

        (*i).run();

    cout << '{' << tellers.size() << '}'

         << customers << endl;

    // If line is too long, add another teller:

    if(customers.size() / tellers.size() > 2)

      tellers.push_back(Teller(customers));

    // If line is short enough, remove a teller:

    if(tellers.size() > 1 && customers.size() / tellers.size() < 2)

      for(TellIt i = tellers.begin();i != tellers.end(); i++)

        if(!(*i).isBusy()) {

          tellers.erase(i);

          break; // Out of for loop

        }//if

  }//while

} ///:~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值