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;
}