STL模板函数使用

  • 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

函数AreCool
insert(Object i)插入元素(自动去重)
erase(value)移除set容器内元素值为value的所有元素返回移除的元素个数
count(value)查询集合中value的元素个数1(有该元素)/0(无)
find(value)查询是否有元素valueiterator(指针)/ .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");
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值