- sort
特点:排序、有序查找 - vector
特点:类似数组的队列、下标随机访问、尾部快速添加或删除元素、iterator遍历 - set
特点:元素去重、有序排列、iteraor遍历 - map
key去重、下标随机访问、键值对有序排列、映射关系、iterator遍历
排序&有序查找
函数 | 说明 | 返回值 |
---|---|---|
sort(v,v+size,[cmp]) | sort(数组起始地址,其实地址+元素个数,可选比较函数) | |
lower_bound(v,v+size,num) | lowerbound(数组起始地址,起始地址+元素个数,查找目标) | 返回第一个大于等于num的元素地址或越界地址,减数组的起始地址后即元素下标或size(v[size]已越界) |
const int size=7;
int num;
int loc;
cin>>num;
int v[size]={3,2,53,54,2,322,1);
sort(v,v+size);
loc=lower_bound(v,v+size,num)-v;
cout<<loc<<endl;
if(v[loc]==num)
cout<<"found "<<num;
/*排序后:1,2,2,3,53,54,322
输入:5
输出:4
输入:2
输出:1
found 2
*/
vector
函数 | 说明 | 返回值 |
---|---|---|
clear() | 清空vector | |
empty() | 检查是否为空 | true/false |
push_back(Object i) | 添加到数组尾部 | |
pop_back() | 从尾部删除一个元素 | 无 |
resize(int size) | 重新调整数组大小 |
/*
题目大意:n个木块分别标号1~n,一开始分别放在1~n号位置上,
模拟4种操作:1.move a onto b:把a号木块放在b上,b上如果有木块要先把木块返回其号码对应的位置
2.move a over b:把a放在b所在木块堆的顶部
3.pile a onto b:把a所在木块堆搬到b上面,b上面如果有木块要先把木块返回其号码对应的位置
4.pile a over b:把a所在木块堆搬到b所在木块堆的顶部
关键:1.vetcor+数组来模拟位置1~n的木块堆
2.4个操作都可以通过3个工具函数实现:findBlock():定位木块的堆和堆中的下标、back():木块归位、move():搬木块(堆)
*/
#include<iostream>
#include<string>
#include<vector>
using namespace std;
const int tot = 100;
int n;
vector<int>b[tot];
//定位a号木块目前所在的位置堆号以及堆中所处的下标
void findBlock(int a, int&p, int&h) {
for(p=1;p<=n;p++)
for (h= 0; h < b[p].size(); h++)
{
if (b[p][h] == a) return;
}
}
//将p号位置堆中下标h之后(不包括h)的元素归位
void back(int p, int h) {
for (int i = h + 1; i < b[p].size(); i++)
b[b[p][i]].push_back(b[p][i]);
b[p].resize(h+1);
}
//将p1堆中p1[h]元素和其之后的木块搬到p1堆上面
void move(int p2, int p1, int h) {
int i = h ;
while (h<b[p1].size()) {
b[p2].push_back(b[p1][h]);
h++;
}
b[p1].resize(i);
}
void print() {
for (int i = 1; i <= n; i++) {
cout << i << ":";
for (int j = 0; j < b[i].size(); j++)
cout << b[i][j] << " ";
cout << endl;
}
}
int main() {
cin >> n;
while (n > 0) {
for (int i = 1; i <= n; i++)
{
b[i].clear();
b[i].push_back(i);
}
//前半段命令、后半段命令
string command1,command2;
//堆号、下标号、木块号
int p1, p2, h1, h2, num1, num2;
cin >> command1;
while (command1[0] != 'q') {
cin >> num1 >> command2 >> num2;
findBlock(num1, p1, h1);
findBlock(num2, p2, h2);
//木块在同一个堆中时无法操作
if (p1 == p2) {
cin >> command1;
continue;
}
if (command1[0] == 'm') {
back(p1, h1);//把p1队列的h1下标之后的元素复位
}
if (command2[1] == 'n')
back(p2, h2);
move(p2, p1, h1);//把p1队列从h1开始之后的元素搬到p2队列后面
print();
cin >> command1;
}
n = -1;
cin >> n;
}
}
set
函数 | Are | Cool |
---|---|---|
insert(Object i) | 插入元素(自动去重) | |
erase(value) | 移除set容器内元素值为value的所有元素 | 返回移除的元素个数 |
count(value) | 查询集合中value的元素个数 | 1(有该元素)/0(无) |
find(value) | 查询是否有元素value | iterator(指针)/ .end()(集合中无该元素) |
empty() | 判断是否为空 | true ,false |
size() | 集合大小 | int |
clear() | 清空集合 | |
end() | 集合尾部(迭代器) | 指针 |
begin() | 集合头部(迭代器) | 指针 |
例题5-3 安迪的第一个字典(Andy’s First Dictionary,Uva 10815)输入一个文本,找出所有不同的单词(连续的字母序列),按字典序从小到大输出。 单词不区分大小写。
/*
1.stringstream用法
2.set用法
*/
#include<iostream>
#include<string>
#include<sstream>
#include<set>
#include<cctype>
using namespace std;
int main() {
string word;
stringstream ss;
char c;
set<string>words;
while ((c = cin.get()) != EOF) {
if (isalpha(c)) {
toupper(c);
ss <<c;
}
else
ss << " ";
}
//使用stringstream来分割单词
while (ss >> word) words.insert(word);
//使用迭代器遍历set,set自动将元素从小到大排列,所以放在set中的元素对象需要重载<操作符
for (set<string>::iterator i = words.begin(); i != words.end(); i++) {
cout << *i << endl;
}
}
map
map使用经验总结:
1.支持使用key随机访问,不支持使用value随机访问
2.find(key) 与count(key 基于key查找键值对是否存在
3.map中key不能重复,但是多个不同的key的value可以相同
4.学会如何设计映射关系,如此题中存在两个映射关系:map中编码映射为次数,vector原始单词通过toup和sort映射为编码
例题:
/*
题目:输入一些单词,以'#'结束。找出所有满足如下条件的单词:该单词不能通过字母重排,得到输入文本中的另外一个单词。 在判断是否满足条件时,字母不分大小写,但在输出时应保留输入中的大小写,按字典序进行排列(所有大写字母在所有小写字母的前面)。
*/
#include<iostream>
#include<string>
#include<algorithm>
#include<map>
#include<vector>
#include<cctype>
using namespace std;
//编码单词,转换成大写
void toup(string s1,string &s2) {
s2 = s1;
for (int i = 0; i < s2.size(); i++)
s2[i] = toupper(s2[i]);
}
int main() {
string word;
string code;
vector<string>words;
vector<string>ans;
map<string, int>mapping;
cin >> word;
while (word.size() > 0) {
if (word[0] == '#') break;
words.push_back(word);
toup(word, code);
sort(code.begin(), code.end());
if (mapping.count(code) == 0)
mapping[code] = 0;
mapping[code]++;
word = "";
cin >> word;
}
for (int i = 0; i < words.size(); i++)
{
toup(words[i], code);
sort(code.begin(), code.end());
if (mapping[code] == 1)
ans.push_back(words[i]);
}
sort(ans.begin(), ans.end());
for (int i = 0; i < ans.size(); i++)
cout << ans[i] << endl;
system("pause");
}