目录:
一:学习内容
1:vector
2:pair
3:结构体中的运算符重载
二:用所学解决的问题
三:本周感想
学习内容:
vector基本用法:
1.赋值方式:
- vectorvec = { 1, 2, 3, 4, 5 };//赋初始值为1,2,3,4,5
- vectorvec1({ 5, 4, 3, 2, 1 });
- vectorvec2(vec1);//相当于:vectorvec2=vec1;
- vectorvec3(10, 2);//构造大小为10的容器 全部初始化为2
- vectorvec4(10);//构造大小为10的容器 不初始化
for(int i = 0; i < 10; i++)
{
vec1.push_back(i+6);
}// 会重新申请内存,内存重新申请原则 每次多申请一半
//vect1=0 1 2 3 4 6 9 13 19 28 42 63 94
vec.push_back(6);//从后面插入一个数
2.访问:
cout << vec[2] << endl;//3 直接通过下标访问
cout << vec[0] + 2 << endl;//3 通过偏移量的方式访问
3.迭代器:
//3.1.遍历
vector::iterator it;//定义迭代器变量it
for (vector::iterator it = vec.begin(); it != vec.end(); it++)
for (it = vec.begin(); it != vec.end(); it++)
{
cout << *it;
}
cout << endl;
//12345
for (auto i = vec1.begin(); i != vec1.end(); i++)//也可以用auto自动识别类型,begin()返回第一个元素的迭代器,end() 返回的最后一个元素后面位置的迭代器 (超尾迭代器)
{
cout << *i;
}
cout << endl;
//54321
//vectorreverse_iterator ;//反向迭代器类型
for (auto it2 = vec2.rbegin(); it2 != vec2.rend(); it2++)//反向迭代器
{ //rbegin 指向最后一个元素的位置 返回的是反向迭代器
//rend()指向最开始元素的前面那个位置 ++是从后向前
cout << *it2 ;
}
cout << endl;
//12345
4.插入:
vec.push_back(6);//从后面插入一个数
vec.insert(vec.begin(), 6);//在begin()位置插入(6),//vec=612345
vec1.insert(vec1.begin(),5,6);//在begin()位置插入5个6, // vec1=6666654321
vec2.insert(vec2.begin()+2, vec2.begin()+3,vec2.end());//在begin()+2(第二个位置之后)插入区间vec2.begin()+3到vec2.end()数据,//vec2=5421321//最好不要插入本身内部区间。
5.删除:
vec.erase(vec.begin());//删除指定第一个元素
vec.erase(vec1.begin()+2,vec1.end());//删除区间元素
vec.clear();//删除全部元素,相当于:vec.erase(vec.begin(),vec.end());
vec.pop_back();//删除vector尾部元素;
6.at函数:
vec.at(3);//*(vec.begin()+3) //会检查是否越界 越界会引发异常
7.排序:
sort(vec.begin(), vec.end());//没第三个参数默认升序排序,
sort(vec.begin(), vec.end(), compare);//按compare函数进行排序;
stable_sort(vec.begin(), vec.end());
//这个函数和sort的用法一样,但比sort更稳定。
8.反转:
reverse(vec.begin(), vec.end());//反转 12345–>54321
9.size函数:
vec.size();//返回当前容器的大小
10.capacity函数:
vec.capacity();//返回当前容器的容量,即元素个数
11.resize函数:
vec.resize(10);//为向量指定一个新容量
12.交换
swap(vec, vec1);//交换两个向量的元素
13.empty函数
vec.empty();//如果vec不含任何元素返回真,否则返回假;
pair基本用法:
1:定义(构造函数以及初始化)
#include< utility >//pair头文件
pair<int,int> p1; //创建一个空的pair对象(使用默认构造),采用值初始化。
pair<int,int> p1(1, 2); //创建一个pair对象,其中first成员初始化为1,second成员初始化为2。
pair<int,int>p3(p2) //创建一个pair对象p3,将p2对象完全拷贝给p3;
make_pair(v1, v2); // 以v1和v2的值创建一个新的pair对象,其元素类型分别是v1和v2的类型。
p1.first; // 返回对象p1中名为first的公有数据成员
p1.second; // 返回对象p1中名为second的公有数据成员
2:元素的访问:
pair<int,int> p1(1, 2); //创建一个pair对象,其中first成员初始化为v1,second成员初始化为v2。
cout<<p1.frist<<" "<<p1.second<<endl;//输出 1 2 ;
3:sort函数
pair<int,int> itv[n];
sort(itv,itv+n);//默认升序,当frist不相等时按照frist升序,否则按照second升序;
sort(itv,itv+n,compare);//还可以定义一个compare函数,按照函数排序
4: 生成新的pair对象
还可以利用make_pair创建新的pair对象:
pair<int, double> p1;
p1 = make_pair(1, 1.2);
cout << p1.first << p1.second << endl;//输出1 1.2;
5:通过tie获取pair元素值
在某些清况函数会以pair对象作为返回值时,可以直接通过std::tie进行接收。比如:
pair<string, int> getPreson()
{
return make_pair("Lily", 17);
}
int main()
{
string name;
int ages;
tie(name, ages) = getPreson();
cout << "name: " << name << ", ages: " << ages <<endl;
return 0;
}//输出 Lily,17;
结构体中的简单运算符重载:
想象一下当你要对结构体进行排序的时候是不是要先写一个compare函数来定义按结构体的那一个对象进行如何的排序,例如:
bool cmp(node x,node y)
{
return x.data<y.data;
}
然后再进行sort排序;
在结构体中进行运算符重载实际上就是将定义函数哪一步放在你所定义的结构体中例如:
struct node
{
int data;
bool operator < (const node b)const//关键字 operator,对 < 进行重载
{
return data < b.data;
}
};
对运算符进行重载实际上就相当于函数的调用,当进行对data的比较时就是在这个结构体中调用了b这个结构体的data对象。这样再进行sort排序时就会按照重载函数进行排序了。
用所学解决的问题
1)结构体中的简单运算符重载例题
整数区间。请编程完成以下任务:
1. 读取闭区间的个数及它们的描述;
2.找到一个含元素个数最少的集合,使得对于每一个区间,都至少有一个整数属于该集合,输出该集合的元素个数。
【输入】
首行包括区间的数目n,1<=n<=10000,接下来的n行,每行包括两个整数a,b,被一空格隔开,0<=a<=b<=10000,它们是某一个区间的开始值和结束值。
【输出】
第一行集合元素的个数,对于每一个区间都至少有一个整数属于该区间,且集合所包含元素数目最少。
【样例输入】
4
3 6
2 4
0 2
4 7
【样例输出】
2
【算法分析】
•首先按b1<=b2<=…<=bn排序。 每次标记当前区间的右端点x,并右移当前区间指针,直到当前区间不包含x,再重复上述操作。
•如下图,如果选灰色点,移动到黑色点更优。
#include<bits/stdc++.h>
using namespace std;
struct A
{
int a,b;
bool operator <(const A x)const
{
return b<=x.b;
}
} aa[1001];
int sum=0,n,m;
main()
{
cin>>n;
for(int i=1; i<=n; ++i)
cin>>aa[i].a>>aa[i].b;
sort(aa+1,aa+n+1);
for(int i=1,x=-1; i<=n; ++i)
{
if (x>=aa[i].a)
continue;//如果当前区间包含标记点,就跳过。
++sum;
x=aa[i].b; //更新标记点。
}
cout<<sum<<endl;
return 0;
}
2)vector运用例题
你想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j ,都有一个尺寸 sj 。如果 sj >= gi ,我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。注意:你可以假设胃口值为正。一个小朋友最多只能拥有一块饼干。
原则是大尺寸的饼干分给胃口大的孩子。
示例:
输入: 1,2,3
1,1
输出: 1
#include<vector>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
int aa(vector<int>& g, vector<int>& s) //胃口是g,饼干是s
{
if(g.empty()|| s.empty())
return 0;
sort(g.begin(),g.end());
sort(s.begin(),s.end());
int res=0, index=s.size()-1;
for(int i=g.size()-1; i>=0;)
{
if(index>=0)
{
if(g[i]<=s[index])
{
res++;
index--;
}
i--;
}
else
{
break;
}
}
return res;
}
int main()
{
char a[10010];
vector<int>g;
vector<int>s;
memset(a,0,sizeof(a));
gets(a);
{
for(int i=0; i<sizeof(a); i+=2)
{
g.push_back(a[i]-'0');
if(a[i+1]!=',')
break;
}
}
memset(a,0,sizeof(a));
gets(a);
for(int i=0; i<sizeof(a); i+=2)
{
s.push_back(a[i]-'0');
if(a[i+1]!=',')
break;
}
cout<<aa(g,s)<<endl;
}
3)pair运用例题
有n项工作,每项工作分别在Si开始,Ti结束。例如S={1,2,4,6,8},T={3,5,7,8,10}。对每项工作,你都可以选择与否,若选择参加,则必须至始至终参加全程参与,且参与工作的时间段不能有重叠。(如下图)你最多能选择几项工作。
#include<utility>
#include<iostream>
#include<algorithm>
using namespace std;
const int n = 5;
int S[n]={1,2,4,6,8};
int T[n]={3,5,7,9,10};
pair<int, int> itv[n];//对工作排序的pair数组
int solve()
{
//为了让结束时间早的工作排在前面,把T存入first,把S存入second
for(int i = 0; i < n; i ++) {
itv[i].first = S[i];
itv[i].second = T[i];
}
sort(itv, itv + n);
int count = 0;//选取的结果
int t = 0; //最后所选工作的结束时间
for(int i = 0; i < n; i ++) {
if(t < itv[i].first) {
count ++;
t = itv[i].second;
}
}
return count;
}
int main() {
int k=solve();
cout << k<< endl;
return 0;
}
本周感想
通过本次学习扩充了更多知识,掌握了更多简便编程的方法,当然本次学习以贪心思想展开的,对贪心的概念也有了更加深入的理解,我觉得可以把“贪心”当做以后做事的行为标准,事事寻找最优解,不局限于仅有的知识,对各种知识都要“贪心”多去了解并掌握运用。每周都要丰富知识充实自己呀!!贪就完事了。