STL 使用技巧

来源:互联网 发布:python 金字塔 编辑:程序博客网 时间:2024/06/15 07:16

         今天写了一个程序,需要用到排序,还有容器。那不用说,在VC里肯定直接想到STL了,容器我选择了LIST,LIST是最灵活的,效率也高。然后发现使用起来不是那么得心应手,虽然都知道在哪里找到答案,但毕竟要查就不是那么顺手了。所以写完后赶快记录下来。以便以后返查,顺便开个文章专门讲STL使用的技巧。当然,如果以后再有心得,这文章就会继续增加。

 

这次主要用了list,所以下面记录几个list可能平时比较难解决的问题。

 

list如何排序,升序和降序?

    把数据加进list中之后,要排序就简单了,就调用它的sort()函数就行了,例如:

 

    list<int> lst;

    lst.push_back(1);

    lst.push_front(2);

    lst.push_back(5);

    lst.sort();

    这样的话,lst里本来是2、1、5的顺序排列的,sort之后就变成了1、2、5也就是升序排列。

 

    那如果我们要降序排列呢?可以这样:

    lst.sort( greater<int>() );

    这样的话,list里面就变成了5、2、1的顺序了!

    

 

list容器如何容纳自定义类型?

 上面的那个list是容纳了int类型,如果我们要容纳自定义的类型怎么办呢??

首先我们需要定义一个类,比如下面的这个类:

class cStyleAndCount
{
 public:
  cStyleAndCount()
 {
  m_strStyleCount = "";
  m_strCount = "";
  m_nCount = 0;
 }
 cStyleAndCount& operator = (const cStyleAndCount &other)
 {
  if(this == &other)
   return *this;

  m_strStyleCount = other.m_strStyleCount;
  m_strCount = other.m_strCount;

  return *this;
 }

 friend int operator<(const cStyleAndCount &left,
      const cStyleAndCount &right)
 {
  return left.m_nCount < right.m_nCount;
 }

 friend int operator>(const cStyleAndCount &left,
  const cStyleAndCount &right)
 {
  return left.m_nCount > right.m_nCount;
 }

 CString m_strStyleCount;
 CString m_strCount;
 int m_nCount;
};

 

我们可以看到,这个类里重载了几个运算符,<、>、=,这几个运算符重载了之后,那list就可以容纳我们的自定义类型了,本来 > 都不用重载,但为了能降序排列,就要做多一步了。

 

接下来的使用和上面第一个问题的使用一样了!

 

遍历list?

 

本来STL里的遍历都很简单,没什么好说的,但这里主要说一下如果需要改变list某个节点里的数值,那就要用指针访问了。

例如:

list<int>::iterator it;

for(it = lstTmp.begin(); it != lstTmp.end(); it++)

{

        int *n = &(*it);

        // 这里list里的数值也会跟着变化了

        (*n)++;

}

list 还有insert、clear 等函数,这些稍微查一下MSDN就知道了,上面是几个比较常遇到的问题,就先说到这里了。

 

正确使用 stl map 的删除节点(转)

 

STL的map表里有一个erase方法用来从一个map中删除掉指令的节点
eg:
map<string,string> mapTest;
typedef map<string,string>::iterator ITER;

ITER iter=mapTest.find(key);
mapTest.erase(iter);

像上面这样只是删除单个节点,map的形为不会出现任务问题,
但是当在一个循环里用的时候,往往会被误用,那是因为使用者没有正确理解iterator的概念.
像下面这样的一个例子就是错误的写法,
eg.
for(ITER iter=mapTest.begin();iter!=mapTest.end();++iter)
{
cout<<iter->first<<":"<<iter->second<<endl;
mapTest.erase(iter);
}

这是一种错误的写法,会导致程序行为不可知.究其原因是map 是关联容器,对于关联容器来说,如果某一个元素已经被删除,那么其对应的迭代器就失效了,不应该再被使用;否则会导致程序无定义的行为。
可以用以下方法解决这问题:
正确的写法
1.使用删除之前的迭代器定位下一个元素。STL建议的使用方式
for(ITER iter=mapTest.begin();iter!=mapTest.end();)
{
cout<<iter->first<<":"<<iter->second<<endl;
mapTest.erase(iter++);
}

2. erase() 成员函数返回下一个元素的迭代器
for(ITER iter=mapTest.begin();iter!=mapTest.end();)
{
cout<<iter->first<<":"<<iter->second<<endl;
iter=mapTest.erase(iter);
}

    

原创粉丝点击