3月13日(第二周学习总结)
一、所学知识
1.c++stl及STL简单应用
stl中的很多特殊的数据结构可以让程序开发者更加灵活的使用数据。
(1)栈FILO
栈结构可以让数据倒置,可以用来转化进制等(有待学习)
头文件: #include <stack>``
定义:stack<data_type> stack_name;
如:stack <int> s;
操作:
empty() -- 返回bool型,表示栈内是否为空 (s.empty() )
size() -- 返回栈内元素个数 (s.size() )
top() -- 返回栈顶元素值 (s.top() )
pop() -- 移除栈顶元素(s.pop(); )
push(data_type a) -- 向栈压入一个元素 a(s.push(a); )
(2)队列FIFO
头文件: #include <queue>
定义:queue <data_type> queue_name;
如:queue <int> q;
操作:
empty() -- 返回bool型,表示queue是否为空 (q.empty() )
size() -- 返回queue内元素个数 (q.size() )
front() -- 返回queue内的下一个元素 (q.front() )
back() -- 返回queue内的最后一个元素(q.back() )
pop() -- 移除queue中的一个元素(q.pop(); )
push(data_type a) -- 将一个元素a置入queue中(q.push(a); )
(3)动态数组
头文件: #include <vector>
定义:vector <data_type> vector_name;
如:vector <int> v;
操作:
empty() -- 返回bool型,表示vector是否为空 (v.empty() )
size() -- 返回vector内元素个数 (v.size() )
push_back(data_type a) 将元素a插入最尾端
pop_back() 将最尾端元素删除
v[i] 类似数组取第i个位置的元素(v[0] )
(4)sort函数
头文件: #include <algorithm>
sort(begin, end);
sort(begin, end, cmp);
例:
int num[] = {1,5,6,2,9};
1) sort(num, num + 5);//默认从小到大排序num[] = {1,2,5,6,9};
2) bool cmp(int a, int b){
return a > b;
}
sort(num, num + 5, cmp); //num[] = {9,6,5,2,1};
(5)priority_queue优先队列
头文件: #include <queue>
定义:priority_queue <data_type> priority_queue_name;
如:priority_queue <int> q;//默认是大顶堆
操作:
q.push(elem) 将元素elem置入优先队列
q.top() 返回优先队列的下一个元素
q.pop() 移除一个元素
q.size() 返回队列中元素的个数
q.empty() 返回优先队列是否为空
(6)生成排列(没懂)
头文件: #include <algorithm>
bool next_permutation(begin, end);
改变区间内元素的顺序,产生下一个排列。
bool prev_permutation(begin, end);
产生前一个排列。
end为最后一个元素的下一个位置。
(7)upper_bound 和 lower_bound(没懂)
upper_bound(begin, end, value);
返回>value的元素的第一个位置。
lower_bound(begin, end, value);
返回>=value的元素的第一个位置。
num[] = {1,2,2,3,4,5};
lower_bound(num, num + 6, 2)为num + 1
upper_bound(num, num + 6, 2)为num + 3
(8)set 和 multiset(待消化)
头文件: #include <set>
定义:set <data_type> set_name;
如:set <int> s;//默认由小到大排序
如果想按照自己的方式排序,可以重载小于号。
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;
s.insert(elem) -- 安插一个elem副本,返回新元素位置。
s.erase(elem) -- 移除与elem元素相等的所有元素,返回被移除 的元素个数。
s.erase(pos) -- 移除迭代器pos所指位置上的元素,无返回值。
s.clear() -- 移除全部元素,将整个容器清空。
迭代器举例:
multiset <int> :: iterator pos;
for(pos = s.begin(); pos != s.end(); pos++)
... ...
(9) map和multimap(待消化)
所有元素都会根据元素的键值自动排序,map的所有元素都是pair,pair的第一个元素被视为键值,第二个元素为实值。map不允许两个元素有相同的键值,但multimap可以。
头文件: #include <map>
定义:map <data_type1, data_type2> map_name;
如:map <string, int> m;//默认按string由小到大排序
操作:
m.size() 返回容器大小
m.empty() 返回容器是否为空
m.count(key) 返回键值等于key的元素的个数
m.lower_bound(key) 返回键值等于key的元素的第一个可安插 的位置
m.upper_bound(key) 返回键值等于key的元素的最后一个可安 插的位置
操作:
m.begin() 返回一个双向迭代器,指向第一个元素。
m.end() 返回一个双向迭代器,指向最后一个元素的下一个 位置。
m.clear() 讲整个容器清空。
m.erase(elem) 移除键值为elem的所有元素,返回个数,对 于map来说非0即1。
m.erase(pos) 移除迭代器pos所指位置上的元素。
直接元素存取:
m[key] = value;
查找的时候如果没有键值为key的元素,则安插一个键值为key的新元素,实值为默认(一般0)。
2.结构体
(个人理解)
结构体是一种特殊的数据类型,是用c++本身的数据类型拼凑而成的一种新数据类型,个人认为这是“类”这个概念产生的雏形。将结构体看作一个实体物品来看,可以给结构体定义很多的属性,但是没有类那种保护数据的形式和方法,(只是水平有限,仅属于猜想)
在后期的工程中发现结构体不能满足人们在大工程中的需要,所以产生了类。
3.类
(个人理解)
类的产生个人认为与结构体密不可分,类做到了很多结构体做不到的事情,目前了解到类是c++特有的功能之一,对象是一个新的概念,面向对象编程和面向过程编程的不同(个人认为)就是能够简化大工程编程工作,减少工作量(由于将很多程序模块化了,可以在后期的使用中直接调用)
二、所做题目*
(1)山农oj
1’2020_数据结构_栈和队列
01:十进制转化为二进制
#include<iostream>
#include<stack>
using namespace std;
int main()
{
stack<int>s;
int l;
int o;
cin>>l;
while(l!=0)
{
o=l%2;
s.push(o);
l=l/2;
}
while(!s.empty())
{
cout<<s.top();
s.pop();
}
return 0;
}
02:周末舞会
#include<iostream>
#include<queue>
using namespace std;
int main()
{
queue<int>fm;//用fm表示女队
queue<int>m;//用m表示男队
int fn=1,n=1;
int i=0,j=0;
cin>>i>>j;
for(;fn<i+1;fn++)
{
fm.push(fn);
}
for(;n<j+1;n++)
{
m.push(n);
}
int k;//用k来表示有多少首舞曲
cin>>k;
for(int o=0;o<k;o++)
{
cout<<fm.front()<<' '<<m.front()<<endl;
fm.push(fm.front());
m.push(m.front());
fm.pop();
m.pop();
}
return 0;
}
03:火车站中的驶出的火车(待研究)查找的csdn老哥资料忘了是谁了
#include <iostream>
using namespace std;
template<typename DataType>
struct Node
{
DataType data;//数据域
Node<DataType>*next;//指针域
};
template<typename DataType>
class LinkStack
{
public:
LinkStack();//构造函数,初始化一个空链栈
~LinkStack();//析构函数,释放链栈各结点的存储空间
void Push(DataType x);//入栈操作,将元素x入栈
DataType Pop();//出栈操作,将栈顶元素出栈
DataType GetTop();//取栈顶元素(并不删除)
int Empty();//判空操作,判断链栈是否为空栈
private:
Node<DataType>*top;//栈顶指针即链栈的头指针
};
template<typename DataType>
LinkStack<DataType>::LinkStack()
{
top = new Node<DataType>;//生成头结点
top->next = nullptr;//头结点的指针域置空
}
template<typename DataType>
LinkStack<DataType>::~LinkStack()
{
Node<DataType>*q = nullptr;
while(top!=nullptr)//释放链栈的每一个结点的存储空间
{
q = top;//暂存被释放结点
top = top->next;// top指向被释放结点的下一个结点
delete q;
}
}
template<typename DataType>
DataType LinkStack<DataType>::GetTop()
{
if(top==nullptr)
throw "下溢异常";
else
return top->data;
}
template<typename DataType>
void LinkStack<DataType>::Push(DataType x)
{
Node<DataType>*s = nullptr;
s = new Node<DataType>;
s->data = x;//申请结点s数据域为x
s->next = top;
top = s;//将结点s插在栈顶
}
template<typename DataType>
DataType LinkStack<DataType>::Pop()
{
Node<DataType>*p = nullptr;
DataType x;
if(top==nullptr)
throw "下溢";
x = top->data;
p = top;//暂存栈顶元素
top = top->next;//将栈顶结点摘链
delete p;
return x;
}
template<typename DataType>
int LinkStack<DataType>::Empty()
{
if(top==nullptr)
throw "下溢异常";
else
return 0;
}
int main()
{
LinkStack<int>S{
};
int m,n;
cin>>m>>n;
int v;
int j = 1;
while(cin>>v)
{
if(v==1)
{
S.Push(j);
j++;
}
if(v==-1)
cout<<S.Pop()<<" ";
}
return 0;
}
综合5-2-6
#include<iostream>
#include<iomanip>
using namespace std;
struct fs
{
double a,b;
};
int main()
{
fs m,l,c;
char k;
cin>>m.a>>m.b>>l.a>>l.b;
cin>>k;
switch(k)
{
case '+':c.a=m.a+l.a,c.b=m.b+l.b;break;
case '-':c.a=m.a-l.a,c.b=m.b+l.b;break;
case '*':c.a=m.a*l.a-m.a*l.b;
c.b=m.b*l.a+m.a*l.b; ;break;
case '/':c.a=(m.a*l.a+m.b*l.b)/(l.a*l.a+l.b*l.b);
c.b=(l.b*l.a-m.a*l.b)/(l.a*l.a+l.b*l.b);
break;
default:
cout << "input error!" << endl;
return 0;
}
cout << "c=" << c.a;
cout << setiosflags( ios::showpos );
cout << c.b << "i" << endl;
return 0;
}
三、总结
其他程序没有例举的价值,经历这个星期的学习,我感觉对acm课程的了解更多了,acm入门学习的不仅仅是知识,或者说重点不是知识,所学的知识是思维的附属品,我们所学习的是在知识之上的东西,很多知识是要为思维所用的工具,拿贪心算法举例,贪心算法是一种思维方式,局部最优求解全局最优的方式。而这种方式需要的知识是在课上快速补充的,所以我认为,学好acm课程的关键有3点:
1.快速扩充基础知识。
2.深刻理解算法思维。
3.快速上手趁热打铁刷题巩固
最终形成自己的思维体系与知识网络,在遇到不同的题型的时候能够快速提取所需要的知识和题目所需要的知识。