mibbp

数据结构基础

栈:

  一种符合“后进先出”(Last In First Out,LIFO)规则的数据结构,有push和pop两种操作,其中push把元素压入“栈顶”,而pop从栈顶把元素弹出,top取栈  顶元素但不删除。

  STL的栈定义在头文件<stack>中,可以用stack<int>s方式声明一个栈。

例题:集合栈计算机

  有一个专门为了集合运算而设计的“集合栈”计算机。该机器有一个初始为空的栈,并且支持以下操作:
  PUSH:空集“{}”入栈
  DUP:把当前栈顶元素复制一份后再入栈
  UNION:出栈两个集合,然后把两者的并集入栈
  INTERSECT:出栈两个集合,然后把二者的交集入栈
  ADD:出栈两个集合,然后把先出栈的集合加入到后出栈的集合中,把结果入栈
       每次操作后,输出栈顶集合的大小(即元素个数)。例如栈顶元素是A={ {}, {{}} }, 下一个元素是B={ {}, {{{}}} },则:
  UNION操作将得到{ {}, {{}}, {{{}}} },输出3.
  INTERSECT操作将得到{ {} },输出1
  ADD操作将得到{ {}, {{{}}}, { {}, {{}} } },输出3.

分析:

  本题的集合并不是简单的整数集合或者字符串集合,而是集合的集合。为了方便起见,此处为每个不同的集合分配一个唯一的id,则每个集合都可以表示成所包含元素的id集合,这样就可以用stl的set<int>来表示了,而整个栈是一个stack<int>。

  typedef set<int> Set;

  map<Set,int> IDcache;  //把集合映射成id

  vector<Set> Setcache;  //根据id取集合

  //查找给定集合x的id。如果找不到。分配一个新id。

  int ID (Set x){

    if(IDcache.count(x)) return IDcache[x];

    Setcache.push_back(x);  //添加新集合

    return IDcache[x] =Setcache.size()-1;

  }

  对于任意集合s(类型是上面定义的Set),IDcache[s]就是他的id,而Setcache[IDcache[s]]就试s本身,下面的ALL和INS是两个宏:

  #define   ALL(x) x.begin(),x.end()

  #define   INS(x) inserter(x,x.begin())

  分别表示“所有的内容”以及“插入迭代器”,具体作用可以从代码中推断出来。

  stack<int> s;  //题目中的栈

  int n;

  cin>>n;

  for(int i=0;i<n;i++){

  string op;

  cin>>op;

  if(op[0] =='p') s.push(ID(Set() ) );

  else if(op[0]=='D') s.push(s.top());

  else{

  Set x1=Setcache[s.top()]; s.pop();

  Set x2=Setcache[s.top()]; s.pop();

  Set x;

  if(op[0] =='U') set_union ALL(x1),ALL(x2),INS(x));

  if(op[0] == 'I') set_intersection (ALL(x1),ALL(x2),INS(x));

  if(op[0] =='A') {x=x2;x.insert(ID(x1));}

  s.push(ID(x));

}

  cout<<Setcache[s.top()]size()<<endl;

}   

队列:

  一种符合”先进先出“(First In First Out,FIFO)原则的”公平队列“。定义<queue>中,可以用queue<int>s声明一个队列。

优先队列:

  是一种抽象数据类型,行为有些像队列,但先出队列的元素不是先进的,而是队列中优先级最高的元素,这样就可以允许类似于“急症病人插队”这样的事情发生。

  STL的优先队列定义在头文件<queue>中,用"priority_queue<int>pq"来声明。这个pq是一个:越小的整数优先级越低的优先队列”。由于出队元素不是最先进队元素,出队的方法有queue的front()变为了top()。

  自定义类型也可以组成优先队列,但必须为每个元素定义一个优先级。这个优先级并不需要一个确定的数字,只需要能比较大小即可。只要元素定义了“小于”运算符,就可以使用优先队列,一些特殊情况需要使用自定义方式比较优先级,例如,要实现一个“个位数大的整数优先级反而小”的优先队列,可以定义一个结构体cmp,重载“()”运算符,使其看上去像一个函数,然后用“priority_queue<int,vector<int>,cmp>pq"方式定义。

 struct cmp{

  bool operator()(const int a,const int b) const {    //a的优先级比b小时返回true

    return a%10>b%10;

  }

 };

 对于常见的优先队列,STL提供了更为简单的定义方法,例如,越小的整数优先级越大的优先队列可以写成"priority_queue<int,vector<int>,greater<int> >pq。注意!最后两个“>"不用写在一起否则会被很多编译器认为是>>。

例题:丑数

 

posted on 2021-01-20 11:46  mibbp  阅读(107)  评论(0编辑  收藏  举报

导航