vector数据查找方法

用STL编写程序时经常使用vector容器来存储数据,当容器中的数据有序时我们可以采取两种方式:

(1) 利用<algorithm>中的find函数进行查找;

(2) 折半查找。

另外也可以将数据存入hash_map中进行查找,下面来测试比较这两种方法的时间效率。

1. 测试数据集

生成比99999小的所有素数作为查询数据集,查找2到99999之间的所有数。

令数组A存储2~99999之间的所有数,则生成素数的方式

(1) 找到当前最小的数字min;

(2) 然后删除min的所有倍数。

重复这两个过程直到A中所有的数字处理完毕,即找到了2~99999之间的所有素数。

2. 效率比较

利用find函数查找需要2745ms,利用折半与hash_map均只需要0ms。

当数字增加到999999时,折半耗时63ms,hash_map耗时31ms。

当数字增加到9999999时,折半耗时577ms,hash_map耗时499ms。

注:hash_map中无法初始化桶的个数会降低hash的速度。(欢迎大家告知如何初始化)

3. 分析

实际遇到的问题:在处理大规模图数据的过程中遇到了vector能存储完所有的图数据,而hash_map却不能。即vector存储的数据规模比hash_map大。

折半查找只能用于有序的数据的查找,而find无要求。

4. 参考代码

#include <string>
#include <sstream>
#include <time.h>
#include <algorithm>
#include <vector>
#include <iostream>
#include <hash_map>
using namespace std;

class compare
{
	vector<int> dataVector;
	vector<int> findData;
	hash_map<int, int> dataHash;
public:
	compare();
	~compare(void);
	void generalPrime();
	void findTest();
	void binSearch();
	void hashTest();
};

compare::compare()
{
	generalPrime();
}

compare::~compare(void)
{
	findData.clear();
	dataVector.clear();
}

void compare::findTest()
{
	clock_t startTime = clock();
	vector<int>::iterator result;
	int exist = 0;
	for (vector<int>::iterator it = findData.begin(); it < findData.end(); it++)
	{
		result = find(dataVector.begin(), dataVector.end(), *it);
		if (result != dataVector.end())
		{
			//查找成功
			exist++;
		}
	}
	clock_t endTime = clock();
	cout << "exist num: " << exist << " find time " << (double)(endTime - startTime)/CLOCKS_PER_SEC*1000 << "ms" <<endl;
}

void compare::binSearch()
{
	int start;
	int end;
	int middle;
	int exist = 0;
	clock_t startTime = clock();
	for (vector<int>::iterator it = findData.begin(); it < findData.end(); it++)
	{
		start = 0;
		end = dataVector.size() - 1;
		middle = (start + end) / 2;
		while (start <= end)
		{
			if (*it < dataVector[middle])
			{
				end = middle - 1;
			}
			else if (*it > dataVector[middle])
			{
				start = middle + 1;
			}
			else
			{
				break;
			}
			middle = (start + end) / 2;
		}
		if (start <= end)
		{
			exist++;
		}
	}
	clock_t endTime = clock();
	cout << "exist num: " << exist << " binsearch time: " << (double)(endTime - startTime)/CLOCKS_PER_SEC * 1000 << "ms" << endl;
}

void compare::generalPrime()
{
	int maxPrime = 99999;
	int flag;
	vector<bool> visited(maxPrime, true);
	for (int i = 2; i < maxPrime; ++i)
	{
		findData.push_back(i);
		if (visited[i])
		{
			dataVector.push_back(i);
			dataHash[i] = 1;
			flag = i;
			for (int ii = 2, flag = i * ii; flag < maxPrime; ++ii, flag *= ii)
			{
				visited[flag] = false;
			}
		}
	}
}

void compare::hashTest()
{
	clock_t startTime = clock();
	int exist = 0;
	vector<int>::iterator result;
	for (vector<int>::iterator it = findData.begin(); it < findData.end(); it++)
	{
		if (dataHash.find(*it) != dataHash.end())
		{
			exist++;
		}
	}
	clock_t endTime = clock();
	cout << "exist num: " << exist << " hash time " << (double)(endTime - startTime)/CLOCKS_PER_SEC*1000 << "ms" << endl;
}
int main()
{
	compare com;
	com.findTest();
	com.binSearch();
	com.hashTest();
	return 1;
}
时间: 2024-08-16 20:57:19

vector数据查找方法的相关文章

查找算法--线性结构的查找方法

查找基本概念: 查找又称为检索,指从一批记录中找出满足指定条件的某一记录过程.在日常生活中比如通讯录查找,字典查找等经常使用查找方法:在程序设计中,查找在许多程序中需要占用很多时间,因此,一个好的查找方法可以提高程序的运行速度. 主关键字和次关键字: 在需要查找的数据结构中,每条记录一般包含多个数据域.查找条件一般是给定其中的一个或几个域的值,这些作为查找条件的域成为关键字(KEY),如果关键字可以唯一标示数据结构中的一条记录,则称此关键字(Primary Key):若关键字不能唯一区别各个不同

【转】Oracle当中扫描数据的方法

本文将对oracle当中扫描数据的存取方法进行介绍. 1) 全表扫描(Full Table Scans, FTS) 为实现全表扫描,Oracle读取表中所有的行,并检查每一行是否满足语句的WHERE限制条件一个多块读操作可以使一次I/O能读取多块数据块(db_block_multiblock_read_count参数设定),而不是只读取一个数据块,这极大的减少了I/O总次数,提高了系统的吞吐量,所以利用多块读的方法可以十分高效地实现全表扫描,而且只有在全表扫描的情况下才能使用多块读操作.在这种访

Java中vector的使用方法

Vector的使用 vector类底层数组结构的,它包含可以使用整数索引进行访问的组件.不过,vector的大小可以根据需要增大或缩小,以适应创建vector后进行添加或移除项的操作,因此不需要考虑元素是否越界或者会不会浪费内存的问题. 由vector的iterator和listIterator方法所返回的迭代器是快速失败的:也即是它不能并发执行操作.如果在迭代器创建后的任意时间从结构上修改了向量(通过迭代器自身的remove或add方法之外的任何其他方式),则迭代器将抛出ConcurrentM

Liger UI 表格数据查找/通过条件加载数据

api上的例子是在本地过滤的,无法使用,自己摸索了一下. javascript代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 //初始化ligerui控件 $(function (){         maingrid = $("#maingrid").ligerGrid({             columns: [                 {

恢复oracle数据库误删除数据的方法汇总

学习数据库时,我们只是以学习的态度,考虑如何使用数据库命令语句,并未想过工作中,如果误操作一下,都可能导致无可挽回的损失.当我在工作中真正遇到这些问题时,我开始寻找答案.今天主要以oracle数据库为例,介绍关于表中数据删除的解决办法.(不考虑全库备份和利用归档日志) 删除表中数据有三种方法:·delete(删除一条记录)·drop或truncate删除表格中数据 1.delete误删除的解决方法    原理:利用oracle提供的闪回方法,如果在删除数据后还没做大量的操作(只要保证被删除数据的

3.1.3 STL中list、map、vector的使用方法

(一)list的使用方法: 代码: #include <iostream> #include <list> #include <algorithm> #include <numeric> #include <iterator> using namespace std; typedef list<int> LISTINT; typedef list<char> LISTCHAR; int main() { LISTINT l

pytorch:EDSR 生成训练数据的方法

Pytorch:EDSR 生成训练数据的方法 引言 Winter is coming 正文 pytorch提供的DataLoader 是用来包装你的数据的工具. 所以你要将自己的 (numpy array 或其他) 数据形式装换成 Tensor, 然后再放进这个包装器中. 使用 DataLoader 有什么好处呢? 就是他们帮你有效地迭代数据, 举例: import torch import torch.utils.data as Data #utils是torch中的一个模块,Data是进行小

【MM系列】在SAP里查看数据的方法

公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]在SAP里查看数据的方法 前言部分 大家可以关注我的公众号,公众号里的排版更好,阅读更舒适. 需求分析 有些时候我们会对采购订单或者销售订单中的条件问题进行多次分析,无论是消息输出类型还是定价条件或税收条件,当然很多时候我们可以通过查找条件记录的存储表,来查看数据进行分析,这是其中的一种方法,比较直接,但是有的时候却显得不是很方便,要

【转】oracle 中随机取数据的方法

oracle 中随机取数据的方法: 1.快速随机取数据(推荐使用): select * from MEMBER sample(1) where rownum <= 10 2.随机取数据,较慢 select * from (  select * from MEMBER order by dbms_random.value) where rownum<=10 ========原文======== 最近在做系统时用到了随机抽取记录的问题: 上网上查找了很多相关资料,发现了不同的方法及其差异.都是基于