第三周学习体会

一、知识点
1、STL学习总结
栈(stack)
栈是一种先进后出的数据结构,它只有一个出口,只能操作最顶端元素。类似于木桶,只能从顶端放入,顶端取出。
用法:
头文件:#include
定义:stacka;
操作:a.empty():当栈内为空时返回值为1,非空是返回值为0。
a.size():返回栈内元素个数。
a.push():向栈内压入一个元素。
a.pop():去除栈顶元素。
a.top():访问栈顶元素。

队列(queue)
队列时一种先进后出的数据结构,从底端加入元素,顶端取出元素。类似平常生活中的排队情况。
用法:
头文件:#include
定义:queuea;
操作:a.empty():判断队列是否为空,返回值为bool类型。
a.size():返回队列内元素个数。
a.push():向队尾压入一个元素。
a.pop():移除队首元素。
a.front():返回队列中的第一个元素(队首)。
a.back():返回队列内最后一个元素(队尾)。

优先队列(priority_queue)
一个拥有权值观念的queue,自动依照元素的权值排列,权值最高排在前面。缺省的情况下,priority_queue是利用一个max_heap完成的。
头文件:#include
定义:priority q;
操作:q.push(elem):将元素elem置于优先队列。
q.top():返回优先队列的下一个元素。
q.pop():移除一个元素。
q.size()返回队列中元素的个数。
q.empty():返回优先队列是否为空。

集合(set)
头文件:#include
定义:sets;
用法:s.begin():返回只想第一个元素的迭代器。
s.clear():清除所有元素。
s.count():返回bool型,有返回1,无返回0.
s.end():返回只想最后一个元素之后的迭代器,不是最后一个元素。
s.erase():删除集合中元素。
s.find():返回一个指向被查找的元素的迭代器,如果没有找到则返回end()。
s.insert():在集合中插入元素。
s.size():集合中元素数目。
s.swap():交换两个集合变量。
s.max_size():返回集合所能容纳的最大元素数量。
s.find:因为在set中每一个键值只会出现0或1次,所以count()就显得有点多余,二find()则是查找括号中的给定值,若没有找到则返回end()。
注意:在set中每个元素的值都唯一并且系统会自动对set内的元素排序,在实际应用中一般会去对string类排序。

STL泛型算法reverse(反转容器)
头文件:#include
它可以交换vector容器中元素顺序。
例:

vector<int>a={1,2,3,4,5};
reverse(a.begin(),a.end());

这经常会被用于对string类的处理,这会使得操作非常的简便。

unique
头文件:#include
功能:可以进行元素去重。原理是将相邻的重复元素去掉多余的只保留一个,实则是将要去掉的元素放到容器末尾。最后返回不重复元素序列的最后一个值的地址。

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
    int n[10]={1,1,1,3,3,5,5,7,7,8};
    vector<int>a;
    for(int i=0;i<10;i++)
      a.push_back(n[i]);
    vector<int>::iterator b=a.begin();
    vector<int>::iterator c=a.end();
    int len=a.size();
    for(int i=0;i<len;i++)
      cout<<a[i]<<" ";
    cout<<endl;
    sort(b,c);
    a.erase(unique(b,c),c);//或者可以写成a.erase(unique(a.begin(),a.end()),a.end());
    int s=a.size();
    for(int i=0;i<s;i++)
      cout<<a[i]<<" ";
    return 0;
}

输出

1 1 1 3 3 5 5 7 7 8
1 3 5 7 8
Process returned 0 (0x0)   execution time : 0.244 s
Press any key to continue.

以上是一个简单的示例,一般unique使用前都要对容器内元素排序

2、upper_bound(begin,end,value):返回>value的元素第一个位置(满足条件)
lower_bound(begin,end,value):返回>=value的元素第一个位置(满足条件的下一个位置/不满足条件的第一个位置)。
lower_bound-upper_bound:满足条件的元素个数。

3、前缀和

forint i=1;i<=n;i++)
{
  cin>>a[i];
  sum[i]=sum[i-1]+a[i];
}

上述这组代码就是求出了前缀和,他是一种重要的预处理,能大大降低查询的时间复杂度,可以求出在i=1到i=n区间内的某两个区间的数据。

二、题目
Sorting by Swapping
描述
Given a permutation of numbers from 1 to n, we can always get the sequence 1, 2, 3, …, n by swapping pairs of numbers. For example, if the initial sequence is 2, 3, 5, 4, 1, we can sort them in the following way:

2 3 5 4 1
1 3 5 4 2
1 3 2 4 5
1 2 3 4 5

Here three swaps have been used. The problem is, given a specific permutation, how many swaps we needs to take at least.
输入
The first line contains a single integer t (1 <= t <= 20) that indicates the number of test cases. Then follow the t cases. Each case contains two lines. The first line contains the integer n (1 <= n <= 10000), and the second line gives the initial permutation.
输出
For each test case, the output will be only one integer, which is the least number of swaps needed to get the sequence 1, 2, 3, …, n from the initial permutation.
样例输入
2
3
1 2 3
5
2 3 5 4 1
样例输出
0
3

错误代码:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
    int t;
    vector<int>a;
    cin>>t;
    while(t--)
    {
        int n;
        int num=0;
        cin>>n;
        for(int i=1;i<=n;i++)
        cin>>a[i];
        for(int i=0;i<=n;i++)
        {
            while(a[i]!=i)
            {
                swap(a[i],a[a[i]]);
                num++;
            }
        }
        cout<<num<<endl;
    }
    return 0;
}

这道题我想通过看a[i]是否与i相同来判断是否应该调换顺序,但是oj提交之后是Runtime error,是由于数组越界导致的,我忽略了vector动态数组是从0开始,还有在用STL时尽量不要使用swap这类函数,我把vector数组换成了普通的数组就ac了

正确代码如下:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
    int t;
    vector<int>a;
    cin>>t;
    while(t--)
    {
        int n;
        int num=0;
        cin>>n;
        for(int i=1;i<=n;i++)
        cin>>a[i];
        for(int i=0;i<=n;i++)
        {
            while(a[i]!=i)
            {
                swap(a[i],a[a[i]]);
                num++;
            }
        }
        cout<<num<<endl;
    }
    return 0;
}

三、总结
通过做递归和贪心这些题,我发现我的基础知识不是很牢固,STL的知识在做题中运用得不熟练,在课上也会时常出现听不懂的现象。由于我之前没有接触过这样的专业知识,所以我应该注重基础的掌握并且像费老师在课上说的那样:选择一件事就要全身心的投入去做。相信在我的努力下,我终将会功课这些难关。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值