逛别人博客的时候,偶然看到这一算法题,顺便用C++实现了一下。

最朴素的解法就是先对数组进行排序,返回第n个数即可。。

下面代码中用的是快速选择算法(不晓得这名字对不对)


 #include <vector>
#include <iostream>
#include <stdexcept>
#include <cstdio> const int QS_EERRMSG_LEN = ; /**
* 快速选择求无序数组中第n大的数字
* 因为select返回的是数组中对象的引用,
* 所以错误处理选择了异常
*/
template <typename T>
class QuickSelect
{
public:
typedef typename std::vector<T>::size_type size_type; /**
* 构造函数
* @brief QuickSelect
* @param array - vector类型的数组
*/
QuickSelect(std::vector<T>& array)
:m_array(array)
{} /**
* 选择第nth大的元素,
* 失败抛出std::out_of_range异常,
* 成功返回得到的元素
* @brief select
* @param nth
* @return
*/
const T&
select(size_type nth) throw(std::out_of_range)
{
//s_pos即第n大在排序之后数组中的下标
size_type s_pos = m_array.size() - nth; if(s_pos > m_array.size()){
char errmsg[QS_EERRMSG_LEN]; std::snprintf(errmsg, QS_EERRMSG_LEN, "Array access violation:{access:%ld range_length:%ld begin:%ld}.", nth, m_array.size(), );
std::out_of_range oor(errmsg);
throw oor;
} return this->select_pos(s_pos, , m_array.size());
} /**
* @brief select
* @param nth
* @param begin
* @param end
* @return
*/
const T&
select(size_type nth, size_type begin, size_type end) throw(std::out_of_range)
{
size_type array_size = m_array.size(); if(begin > array_size || end > array_size || end < begin){
char errmsg[QS_EERRMSG_LEN]; std::snprintf(errmsg, QS_EERRMSG_LEN, "The begin or end are not correct:{array_size:%ld begin:%ld end:%ld}.", array_size, begin, end);
std::out_of_range oor(errmsg);
throw oor;
} //要查找范围的长度
size_type range_length = end - begin + ; //要查找的第n大的元素在当前范围内的位置
size_type s_pos = range_length - nth; if(s_pos > range_length){
char errmsg[QS_EERRMSG_LEN]; std::snprintf(errmsg, QS_EERRMSG_LEN, "Array access violation:{access:%ld range_length:%ld begin:%ld}.", nth, range_length, begin);
std::out_of_range oor(errmsg);
throw oor;
}
else return this->select_pos(s_pos, begin, end);
}
private:
/**
* pos表示的是元素从begin开始的位置
* @brief select_pos
* @param pos
* @param begin
* @param end
* @return
*/
const T& select_pos(size_type pos, size_type begin, size_type end)
{
T& pivot = m_array[begin];
size_type swap_pos = begin; if(begin == end){
return m_array[pos];
} //进行一次快速排序
for(size_type i = begin + ;i < end;i ++){
if(m_array[i] < pivot){
std::swap(m_array[i], m_array[swap_pos ++]);
}
} //数组元素个数为奇数时多交换一次
if(m_array.size() % != ){
if(m_array[end - ] < pivot){
std::swap(m_array[end - ], m_array[swap_pos ++]);
}
} if(swap_pos - begin == pos){
return m_array[swap_pos];
}
else if(swap_pos - begin < pos){
return this->select_pos(pos, swap_pos + , end);
}
else{
return this->select_pos(pos, begin, swap_pos);
}
} /**
* @brief m_array
*/
std::vector<T>& m_array;
};


然后为了测试方便,实现vector输出,很简单的输出

 namespace std{

 template <typename T>
std::ostream& operator <<(std::ostream& out, const std::vector<T>& array)
{
for(auto e:array){
out << e <<" ";
}
out <<std::endl; return out;
} }

下面是测试用例

 int main()
{
std::vector<int> some{,,,,}; std::cout <<some; QuickSelect<int> qs(some); std::cout <<qs.select()<<std::endl; return ;
}

结果输出为

[root@localhost MYJOURNEY]# g++ quick_select.cpp -std=c++
[root@localhost MYJOURNEY]# ./a.out [root@localhost MYJOURNEY]#

求一无序数组中第n大的数字 - 快速选择算法的更多相关文章

  1. 无序数组中第Kth大的数

    题目:找出无序数组中第Kth大的数,如{63,45,33,21},第2大的数45. 输入: 第一行输入无序数组,第二行输入K值. 该是内推滴滴打车时(2017.8.26)的第二题,也是<剑指of ...

  2. [LeetCode] Kth Largest Element in an Array 数组中第k大的数字

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  3. [LeetCode] 215. Kth Largest Element in an Array 数组中第k大的数字

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  4. 前端算法题:找出数组中第k大的数字出现多少次

    题目:给定一个一维数组,如[1,2,4,4,3,5],找出数组中第k大的数字出现多少次. 例如:第2大的数是4,出现2次,最后输出 4,2 function getNum(arr, k){ // 数组 ...

  5. 无序数组中第K大的数

    1. 排序法 时间复杂度 O(nlogn) 2. 使用一个大小为K的数组arr保存前K个最大的元素 遍历原数组,遇到大于arr最小值的元素时候,使用插入排序方法,插入这个元素 时间复杂度,遍历是 O( ...

  6. 查找无序数组中第K大的数

    思路: 利用快速排序的划分思想 可以找出前k大数,然后不断划分 直到找到第K大元素 代码: #include <iostream> #include <algorithm> # ...

  7. 如何寻找无序数组中的第K大元素?

    如何寻找无序数组中的第K大元素? 有这样一个算法题:有一个无序数组,要求找出数组中的第K大元素.比如给定的无序数组如下所示: 如果k=6,也就是要寻找第6大的元素,很显然,数组中第一大元素是24,第二 ...

  8. SQL Server 2008 R2——查找最小nIndex,nIndex存在而nIndex+1不存在 求最小连续数组中的最大值

    =================================版权声明================================= 版权声明:原创文章 谢绝转载  请通过右侧公告中的“联系邮 ...

  9. 快速查找无序数组中的第K大数?

    1.题目分析: 查找无序数组中的第K大数,直观感觉便是先排好序再找到下标为K-1的元素,时间复杂度O(NlgN).在此,我们想探索是否存在时间复杂度 < O(NlgN),而且近似等于O(N)的高 ...

随机推荐

  1. shell编程-1到100的求和与冒泡排序

    Shell编程 一.  for循环 生成列表 {起始数..结束数} 命令生成列表 `seq [起始数] [步进长度] 结束数 ` for  l in {1..5};do for  l in `seq ...

  2. jQuery代码片段

    禁用页面右键菜单 $(document).bind('contextmenu', function(){ return false; }); 浏览器判断 $.browser.version $.bro ...

  3. mysql函数date_format统计刷选按年月日统计的数据

    /*原型*/ SELECT count(did) AS sum, date_format(releasetime, '%Y-%m-%d') AS releasetime FROM hengtu_dem ...

  4. Hibernate整合Struts2时报错

    今天在整合Hibernate和Struts2的时候遇到一个问题 总是出现各种异常,经过仔细检查,代码本身并没有问题, ----------------------------------------- ...

  5. Core Data (一)备

    序 恩,用Core Data也有一段时间了.大大小小的坑也都坑过了.重来没有认真的记录一次.这次需要好好的理一理Core Data.就当一次绝好的机会记录下来.也为了自己加深认识. 为什么要用Core ...

  6. cf B. Resort

    http://codeforces.com/contest/350/problem/B 从旅馆开始倒着找到一个点它的出度>1的位置为止,比较长度大小,找到一个长度最大的即可. #include ...

  7. hdu 1732 Push Box

    http://acm.hdu.edu.cn/showproblem.php?pid=1732 推箱子和游戏规则一样. #include <cstdio> #include <cstr ...

  8. java设计模式--结构型模式--享元模式

    享元模式 概述 运用共享技术有效地支持大量细粒度的对象. 适用性 当都具备下列情况时,使用Flyweight模式: 1.一个应用程序使用了大量的对象. 2.完全由于使用大量的对象,造成很大的存储开销. ...

  9. DragonBoard810使用记录

    1. 执行~/workdir/Source_Package$ getSource_and_build.sh后该脚本先下载android仓库.repo到~目录,然后将android源码check out ...

  10. Video.js网页视频播放插件

        插件描述:Video.js 是一个通用的在网页上嵌入视频播放器的 JS 库,Video.js 自动检测浏览器对 HTML5 的支持情况,如果不支持 HTML5 则自动使用 Flash 播放器. ...