STL(set)

1,set,multiset

*set,集合,不允许有相同元素存于set中,而multiset可以。

s.empty() -- 返回容器是否为空。

s.count(elem) -- 返回元素值为elem的元素的个数。

s.lower_bound(elem) -- 返回 元素值>= elem的第一个元素位置。

s.upper_bound(elem) -- 返回元素值 > elem的第一个元素的位置。

以上位置均为一个迭代器。

*set默认从小到大排,从大到小重载小于号:

struct new_type{

  int x, y;

  bool operator < (const new_type &a)const{

  if(x != a.x) return x < a.x;

  return y < a.y;

  }

  }

  set <new_type> s;

*查找set中的元素:

cout << "FIND:" << endl;

    iter1 = s1.find("abc");//找“abc”是否在set里

    if(iter1 != s1.end()) {//迭代器没走到最后

        cout << *iter1 << endl;

    }else{

        cout << "NOT FOUND" << endl;

    }

*结构体与set集合

struct T1{       //结构体T1,根据key的大小排序
    int key;
    int value1, value2;
    bool operator<(const T1 &b)const{
        return (key < b.key);
    }
};
int main(){
    set<T1> s;
	set<T1> ::iterator iter1;
	T1 t={2,33,44};//结构体输入的两种方式
	T1 tt;
	tt.key=5;
	tt.value1=22;
	tt.value2=88;
    s.insert(t);
    s.insert(tt);
    cout << "ITERATE:" << endl;
    for (iter1 = s.begin(); iter1 != s.end(); iter1++){//set结构体类型的输出
        cout << (*iter1) .key<<"  "<< (*iter1).value1<<"  "<< (*iter1).value2<< endl;
    }
    cout << "FIND:" << endl;
    iter1 = s.find(t);
    if(iter1 != s.end()) {
         cout << (*iter1) .key<<"  "<< (*iter1).value1<<"  "<< (*iter1).value2<< endl;
    }else{
        cout << "NOT FOUND" << endl;

*例题1:

输入一个文本,找出所有不同的单词(不区分大小写),按字典序从小到大输出。

由于要求每个单词只出现一次

  注意输入时将所有非字母的字符变为空格,用字符串流stringstream得到各个单词。

stringstream(字符串流):头文件<sstream> 对字符串抽取和插入

isalpha():判断是否是英文字母

tolower():转换给定字母为小写

toupper():转换给定字母为大写

#include <iostream>
#include <set>
#include <string>
#include <sstream>
using namespace std;

set<string> dict; //string集合

int main()
{
    string s, buf;
    while(cin >> s)
    {
        for (int i = 0; i<s.length(); ++i)//求字符串长度
            if (isalpha(s[i])) //统一为小写
                s[i] = tolower(s[i]);
            else s[i] = ' ';
        stringstream ss(s); //构造字符串流
        while (ss >> buf)
            dict.insert(buf); //新word加入词典
    }
    for (it = dict.begin(); it != dict.end(); ++it) //遍历输出
        cout << *it << endl;
    return 0;
}

例2:(优先队列与set)

丑数是指不能被2,3,5以外的素数整除的数,即它的质因数只能是2,3,5,把所有丑数从小到大排序,求第1500个丑数。

如1,2,3,4,5,6,8,9,10,12,15…如果不从遍历每个数字判断的角度,而是从产生规则的角度看,最小的丑数是1,而对于任何丑数x,2x、3x、5x也都是丑数,这样就可以用一个优先队列保存所有已经产生的丑数,每次取出最小的丑数衍生出3个丑数,加入优先队列(优先队列默认最大堆,因此要用greater<int>参数声明最小堆优先队列)//像在做素数题时候的筛法一样

由于一个丑数可以有多种产生方式(比如12,15),所以用集合set表示一个数是否被产生过,只有没被产生过时才加入优先队列。由于一个丑数可以有多种产生方式(比如12,15),所以用集合set表示一个数是否被产生过,只有没被产生过时才加入优先队列。由于一个丑数可以有多种产生方式(比如12,15),所以用集合set表示一个数是否被产生过,只有没被产生过时才加入优先队列。

include <iostream>
#include <cstdio>
#include <queue>
#include <set>
#include <vector>
using namespace std;
typedef long long LL;把long long简化
const int base[] = {2,3,5};

int main()
{
    priority_queue<LL, vector<LL>, greater<LL> > pq;
    set<LL> s; //集合标记某个数字是否出现过
    s.insert(1);
    pq.push(1);
    int cnt = 0;
    while (1)
    {
        LL x = pq.top(); pq.pop(); //取出队首的数
        cnt++; //弹出一个数字+1,直到弹出第1500个
        if (cnt == 1500)
        {
            printf("The 1500'th ugly number is <%I64d>.", x);
            break;
        }
        LL tmp;
        for (int i = 0; i<3; ++i)
        {
            tmp = x*base[i]; //产生2x,3x,5x
            if (s.count(tmp) == 0) //没有出现过
            {
                s.insert(tmp); //标记tmp出现过
                pq.push(tmp); //tmp插入队列
            }
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值