STL之List的一些编程练习

#include<iostream>
#include<list>
#include<vector>
using namespace std;
void print(int i){
	cout<<i<<endl;
}

int main(){
	//reverse()逆序 
	list<int> s;
	for(int i=0;i<5;i++)
	s.push_back(i);
	for_each(s.begin(),s.end(),print);
	cout<<"分界"<<endl; 
	s.reverse();
 	for_each(s.begin(),s.end(),print);
	
return 0;
}
/*
问题:
1、merge()带参数那种情况?
2、谓词,unique(谓词) 
*/ 
//empty()与vector相同 

/*****一种强大的构造函数:List(开始位置,结束位置)***********
*****************拷贝构造从开始位置的元素到结束位置前一个元素**
***************参数可以是数组的指针、vector的位置、list的位置** 
	int A[]={1,2,3};
	list<int> aList(A,A+2);
	for(list<int>::iterator it=aList.begin();it!=aList.end();it++)
 	cout<<*it<<endl;
	cout<<"分界线"<<endl;
	vector<int> a;
	a.push_back(11);
	a.push_back(22);
	list<int> tlist(a.begin(),a.end());
	for(list<int>::iterator it=tlist.begin();it!=tlist.end();it++)
 	cout<<*it<<endl;
**************************************/ 

/***********其他构造函数***********
	cout<<"分界线"<<endl;
 	list<int> hlist(tlist);
	for(list<int>::iterator it=hlist.begin();it!=hlist.end();it++)
 	cout<<*it<<endl;
 	cout<<"分界线"<<endl;
 	list<int> flist(5,0);
 	cout<<flist.size();
**************************************/ 

/***********resize()函数***********
	list<int> aList;
	aList.resize(10,10);
	for(list<int>::iterator it=aList.begin();it!=aList.end();it++)
	cout<<*it<<endl; 
**************************************/ 

/***********头尾元素的插入、删除、访问***********
	list<int> aList(5,1);
	aList.push_front(0);//在前面插入 
	aList.push_back(0);//在后面插入 
	for(list<int>::iterator it=aList.begin();it!=aList.end();it++)
	cout<<*it<<endl;
	cout<<"分界线:"<<endl;
	cout<<aList.front()<<endl;//返回最前面的元素 
	cout<<aList.back()<<endl;//返回最后一个元素 
	cout<<"分界线:"<<endl;
	aList.pop_front();//删除最前面的元素 
	for(list<int>::iterator it=aList.begin();it!=aList.end();it++)
	cout<<*it<<endl;
	cout<<"分界线:"<<endl;
	aList.pop_back();//删除最后一个元素 
	for(list<int>::iterator it=aList.begin();it!=aList.end();it++)
	cout<<*it<<endl;
**************************************/ 

/***********assign函数完全改变list中内容***********
	list<int> aList(5,1);
	for(list<int>::iterator it=aList.begin();it!=aList.end();it++)	
	cout<<*it<<endl;
	aList.assign(2,5);//assign函数完全改变list中内容 
	cout<<"分界线:"<<endl;
	for(list<int>::iterator it=aList.begin();it!=aList.end();it++)	
	cout<<*it<<endl;
	cout<<"分界线:"<<endl;
	list<int> bList(2,6);
	for(list<int>::iterator it=bList.begin();it!=bList.end();it++)	
	cout<<*it<<endl;
	cout<<"分界线:"<<endl;
 	bList.assign(aList.begin(),aList.end());//相当与拷贝部分或全部 
 	for(list<int>::iterator it=bList.begin();it!=bList.end();it++)	
	cout<<*it<<endl;
	cout<<"分界线:"<<endl;
	//数组 
	int a[]={0,1,2,3};
    bList.assign(a,a+4);
    for(list<int>::iterator it=bList.begin();it!=bList.end();it++)	
	cout<<*it<<endl;
**************************************/ 

/***********swap函数交换两个List的内容***********
	list<int> s;
	for(int i=0;i<5;i++)
	s.push_back(i);
	cout<<"S更改前:"<<endl;
	for_each(s.begin(),s.end(),print);
	list<int> c;
	for(int i=0;i<3;i++)
	c.push_back(3);
	cout<<"C更改前:"<<endl;
	for_each(c.begin(),c.end(),print);
	s.swap(c);
	cout<<"S更改后:"<<endl;
	for_each(s.begin(),s.end(),print);
	cout<<"C更改后:"<<endl;
	for_each(c.begin(),c.end(),print);

**************************************/ 

/***********insert函数与erase函数(可参考vector)***********
	list<int> s;
	for(int i=0;i<5;i++)
 	s.push_front(i);
	for_each(s.begin(),s.end(),print);
	list<int> c;
	for(int i=0;i<4;i++)
	c.push_back(i);
	cout<<"更改后:"<<endl; 
	s.insert(s.end(),c.begin(),c.end());
	for_each(s.begin(),s.end(),print);
	cout<<"再度更改:"<<endl;
	s.erase(s.begin(),++s.begin());
	//s.begin()+4 出错,因为list随机存储 
	for_each(s.begin(),s.end(),print);

**************************************/ 

/***********list之间的比较***********
	list<int> s;
	for(int i=0;i<5;i++)
 	s.push_front(i);
	for_each(s.begin(),s.end(),print);
	//Wrong
	//cout<<"随机:"<<endl;
	//cout<<s[1]; 
	list<int> c;
	for(int i=0;i<5;i++)
 	c.push_front(i);
	//c.push_back(1);
	cout<<(c==s)<<endl;//1
	cout<<(c>=s)<<endl;//1
	cout<<"分割线:"<<endl;
	list<int> x;
	for(int i=0;i<4;i++)
 	x.push_front(i+2);
 	x.push_back(-1);
 	cout<<(x>s)<<endl;//1
 	
 	所有相同类型的容器都支持关系操作符来实现两个容器的比较:

	1.如果两个容器具有相同的长度而且所有元素都相等,那么两个两个容器相等;否则,就不相等。

	2.如果两个容器的长度不相同,但较短的容器中所有元素都等于较长容器中对应的元素,则称较短的容器小于另一容器。

	3.如果两个容器都不是对方的初始子序列,则它们的比较结果取决于所比较的第一个不相等的元素。

	如果容器内的元素不支持比较大小,则容器就不能比较大小。
 	
 	cout<<"X:"<<endl;
 	for_each(x.begin(),x.end(),print);
 	cout<<"S:"<<endl;
 	for_each(s.begin(),s.end(),print);

**************************************/ 

/*********** sort 和 merge ***********
	 bool gre(int a,int b){
		return a>b;
	}
	 
	list<int> s;
	for(int i=0;i<5;i++)
	s.push_back(i);
	list<int> c;
	for(int i=0;i<4;i++)
	c.push_back(i);
	//s.merge(c);//默认升序
	s.merge(c,gre);//没有完成降序排序 
	s.sort(gre); 
	for_each(s.begin(),s.end(),print);
	
--------------------------------------------

	list<int> s;
	for(int i=0;i<5;i++)
	s.push_back(i);
	list<int> c;
	for(int i=0;i<4;i++)
	c.push_back(i);
	//s.merge(c);//默认升序
	s.merge(c);//没有完成降序排序 
	s.sort(greater<int>());
	for_each(s.begin(),s.end(),print);
		
**************************************/ 

/*********** remove和 remove_if ***********
	bool v(int i){
		return i%2;
	}
	
	list<int> s;
	for(int i=0;i<10;i++)
	s.push_back(i);
	cout<<"初始:"<<endl;
	for_each(s.begin(),s.end(),print);
	s.remove(1);
	cout<<"第一次:"<<endl;
	for_each(s.begin(),s.end(),print);
	s.remove_if(v);
	cout<<"第二次:"<<endl;
	for_each(s.begin(),s.end(),print);
		
**************************************/ 

/*********** splice函数,将list c中指定元素(或范围)插入到位置后面***********
***********list  c中会减少相应多元素**********
	list<int> s;
	for(int i=0;i<5;i++)
	s.push_back(i);
	list<int> c;
	for(int i=0;i<5;i++)
	c.push_back(3);
	s.splice(s.end(),c,c.begin(),c.end());
	cout<<c.size()<<endl;
	for_each(s.begin(),s.end(),print);

**************************************/ 

/*********** remove和 remove_if ***********
	bool v(int i){
		return i%2;
	}
	
	list<int> s;
	for(int i=0;i<10;i++)
	s.push_back(i);
	cout<<"初始:"<<endl;
	for_each(s.begin(),s.end(),print);
	s.remove(1);
	cout<<"第一次:"<<endl;
	for_each(s.begin(),s.end(),print);
	s.remove_if(v);
	cout<<"第二次:"<<endl;
	for_each(s.begin(),s.end(),print);
		
**************************************/ 
	
/*********** unique():删除相邻相同的与unique(谓词):删除与第一个不同的 ***********
*********** sort()+unique()删除全部相同的 ***********
	bool v(int i){
		return i==5;
	} 
	
	
	list<int> s;
	list<int> c;
	not_equal_to<int> Pred;
	s.push_back(1);
	s.push_back(1);
	s.push_back(2);
	s.push_back(1);
	for_each(s.begin(),s.end(),print);
	s.unique();
	cout<<"分割"<<endl;
	for_each(s.begin(),s.end(),print); 
	c.push_back(1);
	c.push_back(1);
	c.push_back(2);
	c.push_back(1);
	cout<<"分割"<<endl;
	for_each(c.begin(),c.end(),print);
	c.sort();
	c.unique(Pred); //删除与第一个不同的 
	//c.unique();删除相同的 
	//c.unique(v);//Wrong
	cout<<"分割"<<endl; 
	for_each(c.begin(),c.end(),print);
**************************************/ 

// list::merge
#include <iostream>
#include <list>

// compare only integral part:
bool mycomparison (double first, double second)
{ return ( int(first)<int(second) ); }

int main ()
{
  std::list<double> first, second;

  first.push_back (3.1);
  first.push_back (2.2);
  first.push_back (2.9);

  second.push_back (3.7);
  second.push_back (7.1);
  second.push_back (1.4);

  first.sort();
  second.sort();

  first.merge(second);

  // (second is now empty)

  second.push_back (2.1);

  first.merge(second,mycomparison);

  std::cout << "first contains:";
  for (std::list<double>::iterator it=first.begin(); it!=first.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

output:
first contains: 1.4 2.2 2.9 2.1 3.1 3.7 7.1
Notice how in the second merger, the function  mycomparison (which only compares the integral parts) did not consider  2.1lower than  2.2 or  2.9, so it was inserted right after them, before  3.1.

第二个程序是c++的Example

STL list容器由于采用了双向迭代器,不支持随机访问,所以标准库的merge(), sort()等功能函数都不适用,list单独实现了merge(),sort()等函数。

s.merge(c);

c中元素会清空

两个问题:

1、merge()

为什么我的调用出错,例子调用正确.?

2、谓词是什么?

c.unique(v);//Wrong

为什么这个会出错?


SOLUTION:

1.先附原型:

  template<typename _Tp, typename _Alloc>
    template <typename _BinaryPredicate>
      void
      list<_Tp,_Alloc>::
      unique(_BinaryPredicate __binary_pred)
      {
        iterator __first = begin();
        iterator __last = end();
        if (__first == __last) return;
        iterator __next = __first;
        while (++__next != __last)
        {
          if (__binary_pred(*__first, *__next))
            _M_erase(__next);
          else
            __first = __next;
          __next = __first;
        }
      }

  template<typename _Tp, typename _Alloc>
    template <typename _StrictWeakOrdering>
      void
      list<_Tp,_Alloc>::
      merge(list& __x, _StrictWeakOrdering __comp)
      {
	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 300. list::merge() specification incomplete
	if (this != &__x)
	  {
	    iterator __first1 = begin();
	    iterator __last1 = end();
	    iterator __first2 = __x.begin();
	    iterator __last2 = __x.end();
	    while (__first1 != __last1 && __first2 != __last2)
	      if (__comp(*__first2, *__first1))
		{
		  iterator __next = __first2;
		  _M_transfer(__first1, __first2, ++__next);
		  __first2 = __next;
		}
	      else
		++__first1;
	    if (__first2 != __last2)
	      _M_transfer(__last1, __first2, __last2);
	  }
      }
#include<iostream>
#include<list>
#include<vector>
using namespace std;
void print(int i){
	cout<<i<<endl;
}
 bool gre(int a,int b){
	return a>b;
	}
int main(){
	
	 
	list<int> s;
	
	s.push_back(3);
	s.push_back(2);
	s.push_back(1);
	list<int> c;
	
	c.push_back(3);
	c.push_back(2);
	c.push_back(1);
	//s.merge(c);//默认升序
	c.merge(s,gre);//没有完成降序排序 	
 	//c.merge(s,greater<int>());
	for_each(c.begin(),c.end(),print);
	return 0;
}

这个可以了。

// Moves the elements from [first,last) before position.
       void
      _M_transfer(iterator __position, iterator __first, iterator __last)
       { __position._M_node->transfer(__first._M_node, __last._M_node); }
//https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.1/stl__list_8h-source.html 


通过看文档,发现出错原因是因为函数本身的定义,具体原因还需要继续看。


StrictWeakOrdering(严格弱排序)的要求:





2.

官方文档例子:

// list::unique
#include <iostream>
#include <cmath>
#include <list>

// a binary predicate implemented as a function:
bool same_integral_part (double first, double second)
{ return ( int(first)==int(second) ); }

// a binary predicate implemented as a class:
struct is_near {
  bool operator() (double first, double second)
  { return (fabs(first-second)<5.0); }
};

int main ()
{
  double mydoubles[]={ 12.15,  2.72, 73.0,  12.77,  3.14,
                       12.77, 73.35, 72.25, 15.3,  72.25 };
  std::list<double> mylist (mydoubles,mydoubles+10);
  
  mylist.sort();             //  2.72,  3.14, 12.15, 12.77, 12.77,
                             // 15.3,  72.25, 72.25, 73.0,  73.35

  mylist.unique();           //  2.72,  3.14, 12.15, 12.77
                             // 15.3,  72.25, 73.0,  73.35

  mylist.unique (same_integral_part);  //  2.72,  3.14, 12.15
                                       // 15.3,  72.25, 73.0

  mylist.unique (is_near());           //  2.72, 12.15, 72.25

  std::cout << "mylist contains:";
  for (std::list<double>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}
函数实现:

 template<typename _Tp, typename _Alloc>
    template <typename _BinaryPredicate>
      void
      list<_Tp,_Alloc>::
      unique(_BinaryPredicate __binary_pred)
      {
        iterator __first = begin();
        iterator __last = end();
        if (__first == __last) return;
        iterator __next = __first;
        while (++__next != __last)
        {
          if (__binary_pred(*__first, *__next))
            _M_erase(__next);
          else
            __first = __next;
          __next = __first;
        }
      }

看调用:__binary_pred(*__first, *__next)

终于发现了!是两个参数!!

更改后:

#include<iostream>
#include<list>
#include<vector>
using namespace std;
void print(int i){
	cout<<i<<endl;
}
	bool v(int i,int j){
		return i!=j;
	} 
	
int main(){
	list<int> s;
	list<int> c;
	not_equal_to<int> Pred;
	s.push_back(1);
	s.push_back(1);
	s.push_back(2);
	s.push_back(1);
	for_each(s.begin(),s.end(),print);
	s.unique();
	cout<<"分割"<<endl;
	for_each(s.begin(),s.end(),print); 
	c.push_back(1);
	c.push_back(1);
	c.push_back(2);
	c.push_back(1);
	cout<<"分割"<<endl;
	for_each(c.begin(),c.end(),print);
	c.sort();
	//c.unique(Pred); //删除与第一个不同的 
	//c.unique();删除相同的 
	c.unique(v);//Wrong
	cout<<"分割"<<endl; 
	for_each(c.begin(),c.end(),print);
	
	return 0;
}

这样就可以了。

还有:

一个参数的是:Prediate  pred

两个参数是:BinaryPrediate pred


另外附函数解释:

The second version (2), takes as argument a specific comparison function that determine the "uniqueness" of an element. In fact, any behavior can be implemented (and not only an equality comparison), but notice that the function will call binary_pred(*i,*(i-1)) for all pairs of elements (where i is an iterator to an element, starting from the second) and remove i from the list if the predicate returns true.

The elements removed are destroyed.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值