【算法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并不是将数组重复的元素删除了,而原理是不断的将后面不重复的元素覆盖前面重复的元素,这个函数查看它的函数定义可以发现,返回值是最后一个不重复元素下一个元素的坐标的(迭代器),因此在编程实现中一般这样使用:
- 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;
- 数组中:
// 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;
}