今天这篇文章主体部分是为我滴宝贝儿总结的,vector、map、set、iterator的常见用法和通俗理解!
1.vector
大概介绍一下vector是个啥,首先它是一种数据类型,类似于int double这种,然后被vector定义的类型,可以看做是一种数组,因为和一维数组的功能基本一样,只是多了很多内置函数,可以用来方便操作数组内的数!
基本操作:vector<int> vec; (因为vector是模板类,所以需要自带数据类型,这里的int就是定义的vec数组的数据类型,也就是这个数组有若干个int数据),比较好的一点就是不用定义大小,方便扩充
vector<int> vec(5);(定义一个大小为5的向量/数组)
vector<int> vec(5,2);(定义一个大小为5的向量/数组,每个数的值都为2)
下面使用前面定义的vec来展示基本用法:
vec.size()(输出vec向量的大小,也就是数组的大小)
vec.empty()(判断是否为空,输出为0/1,一般用于if语句中作为判断条件)
vec.insert(vec.begin(),666)(把666插入到开头)
vec.insert(vec.begin(),6,666)(把666插入到开头前六个元素)
vec.push_back(666)(把666加入到vec向量中,类似于链表操作)
以及还有一个创建二维数组的用法:
vector<vector<int> > vec2;(设置了一个二维数组,行是vector<int>类型,列是int类型)
vector<string> vec2;(设置了一个二维数组,行符合vector的所有函数特性,列符合string的所有特性)
比如:vector<string> vec2;那么vec2.size()就是行数,vec2[2].length()就是列数
2.map
大概介绍一下map,map也是STL中的一个容器,称为关联式容器,为啥叫关联式容器呢,因为他是处理一对一的数据,类似于函数,而且map内部算法是吧数据放在一个二叉树中,可以使得内部数据是有序的,关键来了,有序!!!这一点很好用。
map内部是key-value对应关系,key官方名称叫做键值,他的作用可以看做是一个索引,查找value所需要的一个外部接口,通过查key就可以找到数据。
对应关系:value =map[key]
基本操作:map <int,string> mymap;(int是key的数据类型,string是value的数据类型)
mymap[i]=arr[i];(key相当于数组arr的下标,value相当于arr的值)
mymap.count(key);(输出是0/1,表示下标为key的value在不在容器中)
mymap.find(key);(输出是指向key的迭代器,也就是value)
mymap.insert(pair<int,string>(666,"小可爱"));(使用pair插入key=666,value="小可爱")
tips:map中的元素是按照key值升序排列,这一点很重要哦,sort函数就不可以用啦!
3.iterator
说完map就得接着说迭代器,因为他俩始终是绑定的,大概说一下啥是迭代器,我们平时访问数组类型都是通过下标访问,包括C++特有的vector也是通过下标访问,但是在C++中提供了更为方便的一种容器,那就是迭代器,所以我们可以把迭代器看做是指针访问(内部其实也是这么写的)。
基本操作:容器类名::iterator 迭代器名(例如map::iterator it; vector::iterator it;等等,准确的说这个叫做正向迭代器,反向的没用过就不说啦)
vector<int>::iteractor it.begin()(迭代器指向vector第一个元素)
vector<int>::iteractor it.end()(迭代器指向最后一个元素的下一个位置,这里切记!!end()是最后一个元素的下一个,超出了范围,但是作为一个闲置位还是很有必要存在的!)
迭代器也满足指针访问的几乎所有用法,当指针就完事儿了!
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
下面重要的来了!!!
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
关于那天宝贝儿用的迭代器方法做那道题,后来想想其实是有道理的,代码可能写的有问题
首先,之前如果用的是map容器,那么进行迭代器元素删除,后面元素不会发生前移,因为map是二叉树结构,删除结点不会导致整体变化,除非在每次删除后主动写iteractor++,那么就会顺延,但是此种操作较为麻烦,我觉得最好的方法是直接用vector向量,比如说你现在第一行提取出来了str[1],str[5],str[9],下面要删掉这三个,并且保持序号全部前移
vector<string> str;
vector<string>::iteractor it;
it=find(str.begin(),str.end(),str[1]);//从头到尾寻找这个元素
str.erase(it);//erase是删除操作,删除后,后续元素在vector中前移
这是目前我能想到的方法,操作起来还是要写很多的,但是方法很对!!
4.set
概念基本和map差不多,但是set不能直接修改内部数据,而且set定义的数组输出是是自动升序排列,且删除重复元素!这个也要留意,这个方法用在提取最大值时候一步就做出来了,所以感叹集成函数的牛批。。。
map是有key+value的数据储存方式,但是set只有关键字也就是值,其余函数用法和map一毛一样,所以只要记住他和map的区别就行,用起来根据不同需求选择!
5.LeetCode
1)#14 最长公共前缀
此题比较简单,不作分析,直接贴代码
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if(strs.size()==0)
{
return "";
}
for(int i=0;i<strs[0].size();i++)
{
char c=strs[0][i];
for(int j=1;j<strs.size();j++)
{
if(i==strs[j].size()||strs[j][i]!=c)
return strs[0].substr(0,i);
}
}
return strs[0];
}
};
2)#15 三数之和
这个题差点做的崩了,测试了三循环方法,超时。。。测试了确定两个数循环第三个数的方法,速度慢且内存占用异常大。。。后来想到了排序,就想到了set,所以就用STL优化了第二种解法,虽然还是很长,但是也算优化了!
首先因为只是找出来三个数,所以我们不用管顺序,那就直接sort排序一波!然后先找一下最大最小值,如果最大值都没0大,或者最小值都大于0.那肯定不存在三数和为零的情况,如果最大最小值一样,也就是全部元素一样,那除了全为0其他就可以全部舍弃了,这个筛选就节约了大量时间!
下面进入主题部分,使用双循环,第一个循环是第一个数下标,第二个是第二个下标,然后利用map的特性,找到值为-(nums[i]+nums[j])的那一个key,返回给其迭代器,如果这个key不是不存在也不是前两个数,那么就把这三个数放入新建的set容器中等待输出,此法我叫他流氓寻找法。。。合理利用map的find函数嘛嘻嘻嘻,全部for完了之后,再把set中的结果输出就好啦
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int> > result;
if(nums.size()<3)
return result;
sort(nums.begin(),nums.end());
map<int,int> m;
set<vector<int> > se;
int minNum=nums[0],
maxNum=nums[0];
for(int i=0;i<nums.size();i++){
minNum=min(minNum,nums[i]);
maxNum=max(maxNum,nums[i]);
m[nums[i]]=i;
}
if(maxNum==minNum){
if(minNum==0){
vector<int> t;
t.push_back(0);
t.push_back(0);
t.push_back(0);
result.push_back(t);
}
return result;
}
if(maxNum<0||minNum>0){
return result;
}
map<int,int>::iterator it;
for(int i=0;i<nums.size();i++){
for(int j=i+1;j<nums.size();j++){
if(i<j){
if(nums[i]+nums[j]+minNum>0||nums[i]+nums[j]+maxNum<0){
continue;
}
it=m.find(-(nums[i]+nums[j]));
if(it!=m.end()&&it->second>j){
vector<int> t;
t.push_back(nums[i]);
t.push_back(nums[j]);
t.push_back(it->first);
se.insert(t);
}
}
}
}
set<vector<int> >::iterator sit=se.begin();
for(;sit!=se.end();sit++){
result.push_back(*sit);
}
return result;
}
};