洛谷做题日常

【算法1-2】排序

P1059 [NOIP2006 普及组] 明明的随机数

题目分析

这道题最主要的就是排序去重两个工作

  • 排序:C++中的sort函数(原因:这个函数因为结合了快速排序以及插入排序和桶排序,会根据不同的规模对于排序策略进行调整,所以速度是所有排序方法中最快的)
  • 去重:采用for循环或者unique函数

C++ STL中的 unique() 函数

unique()函数是C++标准库中的函数,它的作用是去除相邻的重复元素(注意一定是相邻元素,且只保留一个

那下面就有一个问题:它是怎样实现去重的呢?删除吗?

下面我们写一个程序来测试一下:

// 测试程序
#include <bits/stdc++.h>
using namespace std;

int n;
int a[10] = {1, 9, 2, 1, 2, 8, 9, 10, 9, 1};

int main()
{
    // 排序
    sort(a, a + 10);
    cout << "数组排序之后为:";
    for (int i = 0; i < 10; i++)
        cout << a[i] << " ";
    cout << endl;

    // 去重
    unique(a, a + 10);
    cout << "数组去重之后为:";
    for (int i = 0; i < 10; i++)
        cout << a[i] << " ";
    return 0;
}

在这里插入图片描述

结论:可以明显看出unique并不是将数组重复的元素删除了,而原理是不断的将后面不重复的元素覆盖前面重复的元素,这个函数查看它的函数定义可以发现,返回值是最后一个不重复元素下一个元素的坐标的(迭代器),因此在编程实现中一般这样使用:

  1. vector中:
vector<int> vec;
vector<int>::iterator it = unique(vec.begin(), vec.end()); // 获得最后不重复元素的下一个元素的坐标的迭代器
vec.erase(it, vec.end()); // 使用vector的erase函数将后面没用的数据擦除

for (it = vec.begin(); it != vec.end(); it++) // 遍历输出vec中的数据
    cout << *it;
  1. 数组中:
// a是这个将要被去重的数组,N是这个数组的原始长度
int new_len = unique(a, a + N) - a; // 返回的是去重后的数组长度new_len

代码实现1:for循环实现去重

#include <bits/stdc++.h>
using namespace std;

int N;
int a[105];
int len;

int main()
{
    cin >> N;
    for (int i = 0; i < N; i++)
        cin >> a[i];

    sort(a, a + N);
    
    for (int i = 0; i < N; i++)
    {
        if (a[i] != a[i + 1])
            len++;
    }

    cout << len << endl;

    for (int i = 0; i < N; i++)
    {
        if (a[i] != a[i + 1])
            cout << a[i] << " ";
    }
    return 0;
}

代码实现2:unique实现去重

#include <bits/stdc++.h>
using namespace std;

int N;
int a[105];
int len;

int main()
{
    cin >> N;
    for (int i = 0; i < N; i++)
        cin >> a[i];

    sort(a, a + N); // 排序
    len = unique(a, a + N) - a; // 返回去重后的数组长度

    cout << len << endl;

    for (int i = 0; i < len; i++)
        cout << a[i] << " ";
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值