1、一组N个数,确定其中第k个最大值
2017-11-28 15:25
1341 查看
一组N个数,确定其中第k个最大值
《数据结构与算法分析(C语言描述)》一书已购多日,没有时间看,今天重拾,发现确是一本不可多得的好书,从第一章开始看起,决定将书中的每个问题均码一遍,为了兼顾Python和Java的学习,本博客采用三种编程语言同时编写,直到笔者对Python和Java已经很熟练为止。在本书的第1章引论的1.1节中(P1),作者给出了这样的一个问题:
设有一组N个数而要确定其中第k个最大者
作者给出了两种思考的方法:
1、将这N个数读进一个数组中,再通过简单的算法,比如冒泡排序算法,以递减规律排序,然后返回位置k上的数字
2、将前k个数读入数组并递减排序,然后将剩下的元素逐个读入,当新元素被读到时,如果它小于数组中的第k个元素,则忽略,否则就将其放到数组中正确的位置上,同时将数组中的一个元素挤出数组。当算法终止,位于第k个位置的元素返回
首先我们用下面Python代码生成一个存放在F盘的txt文档,保存了10000个随机浮点数。然后我们取第5000个最大的数。
# -*- coding:utf-8 -*- # 采用Python3.6编写 import random import datetime import time dataCount = 10000 def genDataBase1(fileName,dataCount): outp = open(fileName,'w') i = 0 while i<dataCount: value=random.random()*dataCount mLine = "%f\n"%(value) outp.write(mLine) i += 1 outp.close() if __name__ == "__main__": random.seed() start = time.time() genDataBase1('F:\Data Structures and Algorithm Analysis in C\\random_float.txt',dataCount) end = time.time() print('use time:',(end-start)) print('Ok')
1、以下是C++代码:
结论是利用快速排序比冒泡排序速度快很多。C++是在release下生成解决方案,然后在命令行下运行exe程序得到的时间。
C++代码(利用库函数sort快速排序)(在VS2015中编译通过)
时间0.019s,答案为4987.73。
#include <iostream> #include<string> #include<fstream> #include<vector> #include <sstream> #include <time.h> #include<algorithm> using namespace std; int main() { //读取txt的输入流,要#include<fstream> string filename = "F:\\Data Structures and Algorithm Analysis in C\\random_float.txt"; ifstream infile(filename.c_str()); string temp; float value; vector<float> list; clock_t start_time = clock();//声明计时器对象并开始计时 ,要#include <time.h> int k = 5000; while (getline(infile, temp)) { //利用字符串流将字符串转换为浮点数,要#include <sstream> stringstream stream(temp); stream >> value; //将读入的浮点数添加到列表内 list.push_back(value); } sort(list.begin(), list.end()); //对vector的排序函数,要#include<algorithm> value = list[10000 - 5000]; clock_t end_time = clock(); //static_cast是标准转换运算符,确保类型转换成功。CLOCKS_PER_SEC定义了每秒钟包含多少了时钟单元数 cout << "运行时间:" << static_cast<double>(end_time - start_time) / CLOCKS_PER_SEC << "s" << endl;//输出已流失的时间 cout << "答案为:" << value << endl;//输出在10000个数中第5000个大数的值。 getchar(); }
C++代码(利用冒泡排序)(在VS2015中编译通过)
时间0.147s,答案为4987.73。
#include <iostream> #include<string> #include<fstream> #include<vector> #include <sstream> #include <time.h> using namespace std; int main() { //读取txt的输入流,要#include<fstream> string filename = "F:\\Data Structures and Algorithm Analysis in C\\random_float.txt"; ifstream infile(filename.c_str()); string temp; float value; int index_out; int index_in; vector<float> list; clock_t start_time=clock();//声明计时器对象并开始计时 ,要#include <time.h> int k = 5000; while (getline(infile, temp)) { //利用字符串流将字符串转换为浮点数,要#include <sstream> stringstream stream(temp); stream >> value; //将读入的浮点数添加到列表内 list.push_back(value); } //冒泡排序算法 for (index_out = 0; index_out < 10000-1; index_out++) { for (index_in = 0; index_in < 10000 - 1 - index_out; index_in++) { if (list[index_in] > list[index_in + 1]) { value = list[index_in + 1]; list[index_in + 1] = list[index_in]; list[index_in] = value; } } } value = list[10000-5000]; clock_t end_time = clock(); //static_cast是标准转换运算符,确保类型转换成功。CLOCKS_PER_SEC定义了每秒钟包含多少了时钟单元数 cout << "运行时间:" << static_cast<double>(end_time - start_time) / CLOCKS_PER_SEC<< "s" << endl;//输出已流失的时间 cout << "答案为:" << value << endl;//输出在10000个数中第5000个大数的值。 getchar(); }
C++代码(库函数sort快速排序+挤出数组法)(在VS2015中编译通过)
时间0.171s,答案为4987.73。
#include <iostream> #include<string> #include<fstream> #include<vector> #include <sstream> #include <time.h> #include <algorithm> using namespace std; int main() { //读取txt的输入流,要#include<fstream> string filename = "F:\\Data Structures and Algorithm Analysis in C\\random_float.txt"; ifstream infile(filename.c_str()); string temp; float value; int index_out; int index_in; vector<float> list; clock_t start_time=clock();//声明计时器对象并开始计时 ,要#include <time.h> int k = 5000; int i = 0; while (i<k&&getline(infile, temp)) { //利用字符串流将字符串转换为浮点数,要#include <sstream> stringstream stream(temp); stream >> value; //将读入的浮点数添加到列表内 list.push_back(value); i++; } sort(list.begin(), list.end()); //将新数往数组内插入 while (getline(infile, temp)) { stringstream stream(temp); stream >> value; if (value > list[0]) { list[0] = value; sort(list.begin(), list.end()); } } value = list[0]; clock_t end_time = clock(); //static_cast是标准转换运算符,确保类型转换成功。CLOCKS_PER_SEC定义了每秒钟包含多少了时钟单元数 cout << "运行时间:" << static_cast<double>(end_time - start_time) / CLOCKS_PER_SEC<< "s" << endl;//输出已流失的时间 cout << "答案为:" << value << endl;//输出在10000个数中第100个大数的值。 getchar(); }
C++代码(冒泡排序+挤出数组法)(在VS2015中编译通过)
时间0.061s,答案为4987.73。
#include <iostream> #include<string> #include<fstream> #include<vector> #include <sstream> #include <time.h> using namespace std; //往原有数组内插入新数后重排顺序 void update(vector<float> &list) //函数中的形参要用引用值,而不用指针或其他,这也是对引用的一种复习吧 { int index, k = 5000; float value; //冒泡排序算法 for (index = 0; index< k - 1; index++) { if (list[index] > list[index + 1]) { value = list[index + 1]; list[index + 1] = list[index]; list[index] = value; } } } int main() { //读取txt的输入流,要#include<fstream> string filename = "F:\\Data Structures and Algorithm Analysis in C\\random_float.txt"; ifstream infile(filename.c_str()); string temp; float value; int index_out; int index_in; vector<float> list; clock_t start_time=clock();//声明计时器对象并开始计时 ,要#include <time.h> int k = 5000; int i = 0; while (i<k&&getline(infile, temp)) { //利用字符串流将字符串转换为浮点数,要#include <sstream> stringstream stream(temp); stream >> value; //将读入的浮点数添加到列表内 list.push_back(value); i++; } //冒泡排序算法 for (index_out = 0; index_out < k-1; index_out++) { for (index_in = 0; index_in < k - 1 - index_out; index_in++) { if (list[index_in] > list[index_in + 1]) { value = list[index_in + 1]; list[index_in + 1] = list[index_in]; list[index_in] = value; } } } //将新数往数组内插入 while (getline(infile, temp)) { stringstream stream(temp); stream >> value; if (value > list[0]) { list[0] = value; //这里要在update函数中更新vector数组的实参值,因此要传入实参,函数中要用引用值 update(list); } } value = list[0]; clock_t end_time = clock(); //static_cast是标准转换运算符,确保类型转换成功。CLOCKS_PER_SEC定义了每秒钟包含多少了时钟单元数 cout << "运行时间:" << static_cast<double>(end_time - start_time) / CLOCKS_PER_SEC<< "s" << endl;//输出已流失的时间 cout << "答案为:" << value << endl;//输出在10000个数中第5000个大数的值。 getchar(); }
2、以下是Python3.6代码:
Python代码1:不得不说,Python计算的速度、精确度都远比其他语言高,而且代码量很少。
时间0.004999876022338867s,答案为4987.7267。
#-*- coding:utf-8-*- import string import time data=[] start=time.time() for line in open("F:\Data Structures and Algorithm Analysis in C\\random_float.txt"): value=float(line) data.append(value) data.sort() end=time.time() print('use time:',(end-start)) print(data[5000])
Python代码2:注意Python传值而非传引用!
时间6.343999862670898s,答案为4987.7267。
#-*- coding:utf-8-*- import string import time #完全冒泡排序算法 def sort_full(data): output = data[:] #这句话中间冒号说明是完全复制data数组的全部内容 for i in range(9999): #这个范围是0,1,2,3,,,,9998 for j in range(9999-i): if output[j]>output[j+1]: #Python中交换两个值的方法很容易的 output[j],output[j+1] = output[j+1],output[j] return output if __name__=="__main__": data=[] start=time.time() for line in open("F:\D a060 ata Structures and Algorithm Analysis in C\\random_float.txt"): value=float(line) data.append(value) data = sort_full(data) end=time.time() print('use time:',(end-start)) print(data[5000])
3、以下是Java代码:
先占坑
相关文章推荐
- 设计一组N个数,确定其中第k个最大值
- 选择问题(一组N个数确定其中的第K个最大者)
- 剑指offer (30)选择问题-----1.有一组N个数,确定其中第K个最大者;2.求最小的k个数
- 编写一个程序,对用户输入的任意一组数字字符如{3,1,4,7,2,1,1,2,2},输出其中出现次数最多的字符,并显示其出现次数。如果有多个字符出现次数均为最大且相等,则输出最先出现的那个字符和它出现
- 编程题:用一组数组做函数参数来实现,输入两个数,输出其中最大数
- 设有一组N个数,求其中第K个最大者
- 用电压V=10伏的电池给电容器充电,电容器上t时刻的电压为 ,其中V0是电容器的初始电压, 是充电常数。试由下面一组t,V数据确定V0, 。
- 1、 编写一个Java应用程序,对用户输入的任意一组字符如{1,3,4,7,2,1,1,5,2},输出其中出现次数最多且数值最大的字符,并显示其出现次数。
- 长度为n的整数数组,找出其中任意(n-1)个乘积最大的那一组,只能用乘法,不可 以用除法。要求对算法的时间复杂度和空间复杂度作出分析,可以写思路也可以写程序。
- 求在一组N个的数中找出第K个最大数
- 长度为n的整形数组,找出其中的任意n-1个数乘积最大的那一组
- c语言:用户输入10个整数,程序找出其中的最大值和最小值
- 第七周项目3-输入三个整数,输出其中的最大值
- 你有一桶果冻,其中有黄色、绿色、红色三种,闭上眼睛抓取同种颜色的两个。 抓取多少个就可以确定你肯定有两个同一颜色的果冻?(5秒-1分钟)
- 背包问题-堆栈-找出其中一组解(总体积为T,n件物品体积分别是w1,w2,...,w2n,找出若干件恰好装满背包)
- 设计一个算法,通过一趟遍历在单链表确定最大的结点
- 小算法:给定两个字符串,请编写程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串s首先
- 找出数组中第K个最大的数
- squee_spoon and his Cube VI(贪心,找不含一组字符串的最大长度+kmp)
- 数据结构3.11答案 递归的查询单链表的其中的记录,以及最大能够让堆栈crash的值