背景:构造一个无重复的白名单,之后要在里面进行二分查找。故要求名单有序,且无重复,并且要进行二分查找,所以要采用有:随机访问迭代器类型的容器。这类容器有vector,array,deque。显然要vector和deque合适一点,但是deque并没有体现出其两端和中间插入时间为固定而非线性的优势,因为本例都在尾部插入,vector和deque同为固定时间。而deque的随机存储操作时间长,故采用vector。

一.利用STL算法unique

首先要将vector排序,排序后。利用erase配合unique算法。利用一个含有一百万整数,里面重复数字并不太多的情况测试。

  1. #include<fstream>
  2. #include<iostream>
  3. #include <vector>
  4. #include<algorithm>
  5. #include<ctime>
  6. using namespace std;
  7. void main()
  8. {
  9. ifstream fwhite;
  10. int number;
  11. vector<int> white_list;
  12. clock_t cost;
  13. fwhite.open("largeW.txt");
  14. if(!fwhite.is_open())
  15. {//or use .good .fail or directly use ! to judge if the file has been opened successfully
  16. cout<<"can't open file list"<<endl;
  17. exit(EXIT_FAILURE);
  18. }
  19. cost=clock();
  20. while(!fwhite.eof())
  21. {
  22. fwhite>>number;
  23. white_list.push_back(number);
  24. }
  25. cost=clock()-cost;
  26. cout<<"Time to load data : "<<cost<<endl;
  27. sort(white_list.begin(),white_list.end());
  28. white_list.erase(unique(white_list.begin(),white_list.end()),white_list.end());
  29. cost = clock()-cost;
  30. cout<<"Time to remove reduplicative data from vector : "<<cost<<endl;
  31. ofstream fout("sort_white.txt",ios::trunc);
  32. vector<int>::iterator iter=white_list.begin();
  33. while (iter!= white_list.end())
  34. {
  35. fout<<*iter<<endl;
  36. iter++;
  37. }
  38. cost = clock()-cost;
  39. cout<<"Time to write data into file : "<<cost<<endl;
  40. exit(EXIT_SUCCESS);
  41. };

二.利用set配合copy

读数据的时候就用set,然后直接拷贝到vector。但是拷贝的时候要用到insert_iterator来进行插入拷贝。(溢出问题)

  1. #include<fstream>
  2. #include<iostream>
  3. #include <vector>
  4. #include<set>
  5. #include<algorithm>
  6. #include<ctime>
  7. #include <iterator>
  8. using namespace std;
  9. void main()
  10. {
  11. ifstream fwhite;
  12. int number;
  13. vector<int> white_list;
  14. set<int> ori_list;
  15. clock_t cost;
  16. fwhite.open("largeW.txt");
  17. if(!fwhite.is_open())
  18. {//or use .good .fail or directly use ! to judge if the file has been opened successfully
  19. cout<<"can't open file list"<<endl;
  20. exit(EXIT_FAILURE);
  21. }
  22. cost=clock();
  23. while(!fwhite.eof())
  24. {
  25. fwhite>>number;
  26. ori_list.insert(number);
  27. }
  28. cost=clock()-cost;
  29. cout<<"Time to load data : "<<cost<<endl;
  30. insert_iterator<vector<int> > it(white_list,white_list.begin());
  31. copy(ori_list.begin(),ori_list.end(),it);
  32. cost = clock()-cost;
  33. cout<<"Time to copy data from set to vector : "<<cost<<endl;
  34. ofstream fout("sort_white.txt",ios::trunc);
  35. vector<int>::iterator iter=white_list.begin();
  36. while (iter!= white_list.end())
  37. {
  38. fout<<*iter<<endl;
  39. iter++;
  40. }
  41. cost = clock()-cost;
  42. cout<<"Time to write data into file : "<<cost<<endl;
  43. exit(EXIT_SUCCESS);
  44. };

三.时间开销从开始构造容器开始,利用clock计时

第一种耗时:8.477秒

第二种耗时:23.246秒

看出,还是直接用vector就好,然后配合unique好。原因:同样插入100万个整数,set用时过长,经测试用去了约18秒。为主要开销。

第一种:读取文件到vector开销5.852秒,排序并去除重复元素开销3.205秒,写文件开销15.624秒。总耗时约24秒左右。

第二种:读文件到set开销18.893秒,从set拷贝数据到vector开销4.884秒,写文件开销20秒。总耗时约44秒左右。

但是看出程序写文件很慢,本例中采用iterator迭代取值写文件,如果直接采用索引下标会不会更快?或者采用copy函数和stream_interator?

四.在一的基础上,最后写文件时采用下标而不是迭代器

发现并无明显改进。

五.采用统一复制,配合ostream_iterator使用,在此例中速度缩短近一半。

  1. #include<fstream>
  2. #include<iostream>
  3. #include <vector>
  4. #include<algorithm>
  5. #include<ctime>
  6. #include <iterator>
  7. using namespace std;
  8. void main()
  9. {
  10. ifstream fwhite;
  11. int number;
  12. vector<int> white_list;
  13. clock_t cost;
  14. fwhite.open("largeW.txt");
  15. if(!fwhite.is_open())
  16. {//or use .good .fail or directly use ! to judge if the file has been opened successfully
  17. cout<<"can't open file list"<<endl;
  18. exit(EXIT_FAILURE);
  19. }
  20. cost=clock();
  21. while(!fwhite.eof())
  22. {
  23. fwhite>>number;
  24. white_list.push_back(number);
  25. }
  26. cost=clock()-cost;
  27. cout<<"Time to load data : "<<cost<<endl;
  28. sort(white_list.begin(),white_list.end());
  29. white_list.erase(unique(white_list.begin(),white_list.end()),white_list.end());
  30. cost = clock()-cost;
  31. cout<<"Time to remove reduplicative data from vector : "<<cost<<endl;
  32. ofstream fout("sort_white.txt",ios::trunc);
  33. /*vector<int>::iterator iter=white_list.begin();
  34. while (iter!= white_list.end())
  35. {
  36. fout<<*iter<<endl;
  37. iter++;
  38. }*/
  39. //for(unsigned int index = 0;index< white_list.size();index++)
  40. //{
  41. //  fout<<white_list[index]<<endl;
  42. //}
  43. copy(white_list.begin(),white_list.end(),ostream_iterator<int,char>(fout,"\n"));
  44. cost = clock()-cost;
  45. cout<<"Time to write data into file : "<<cost<<endl;
  46. exit(EXIT_SUCCESS);
  47. };

另外:largeW文件是从《算法4》的网站得到的,或者可以采用rand函数先自己制造一个。每行一个int型整数,100万行即可。

【C++】去除vector里重复元素的方法比较的更多相关文章

  1. python去除列表中重复元素的方法

    列表中元素位置的索引用的是L.index 本文实例讲述了Python去除列表中重复元素的方法.分享给大家供大家参考.具体如下: 比较容易记忆的是用内置的set 1 2 3 l1 = ['b','c', ...

  2. php 去除数组中重复元素

    去除数组中重复元素, 找了下可以一下两个函数 php array_flip()与array_uniqure() $arr = array(…………) ;// 假设有数组包含一万个元素,里面有重复的元素 ...

  3. 引用vector里的元素被删除后,引用会怎么样?

    引用的定义不多说,直接看做变量的别名就可以了.有一天写着写着代码,突然想到,如果对vector里某个元素设置引用后,将这个元素从vector里删除会怎么样?我思考了下,认为那个元素会被删除,但是引用还 ...

  4. java去除数组重复元素的方法

    转载自:https://blog.csdn.net/Solar24/article/details/78672500 import java.util.ArrayList; import java.u ...

  5. js判断数组里是否有重复元素的方法

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/longzhoufeng/article/details/78840974 第一种方法:但是下面的这种 ...

  6. pyhon 去除列表中重复元素

    Python set() 函数 描述 set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集.差集.并集等. 语法 set 语法: class set([iterabl ...

  7. JS判断数组中是否有重复元素的方法

    判断数组中是否有重复元素,最容易想到的方法是使用2重循环,逐个遍历,比较,但是这个是最慢,最笨的方法,百度得出了更好的方法. var ary = new Array("111",& ...

  8. 利用filter,巧妙地去除Array的重复元素

    var r, arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry']; r ...

  9. ArrayList中重复元素处理方法.[Java]

    1.使用HashSet删除ArrayList中重复的元素 private static void sortByHashSet() { ArrayList<String> listWithD ...

随机推荐

  1. PHP中的符号 ->、=> 和 :: 的含义(用法)

    php新手经常碰到的问题,->.=> 和 :: 这三个家伙是什么分别都是做什么的啊!看着就很晕. 没关系,下面我们做一下详细的解释,如果你有C++,Perl基础,你会发现这些家伙和他们里面 ...

  2. MATLAB---fopen、fprintf函数

    1 概述 fopen()是个将数据按指定格式读入到matlab中的函数. fprintf()是个将数据按指定格式写入到文本文件中的函数. 2 用法 2.1 fopen函数 matlab中fopen函数 ...

  3. nodejs+express 初学(一)

    以下都是windows环境 1.下载nodejs http://www.nodejs.org/download/ 然后安装 2.确认已经安装完成 . node -v 3.安装express 注意: 是 ...

  4. LINUX用户身份切换

    Su 命令作用 su的作用是变更为其它使用者的身份,超级用户除外,需要键入该使用者的密码. 使用方式 su [-fmp] [-c command] [-s shell] [--help] [--ver ...

  5. PHP苹果推送实现(APNS)

    以下资料网上收集整理得来 1.在ios dev center制作相关证书和文件用客户端实现(不再赘述,网上很多,) 网上教程: http://blog.csdn.net/lizhenning87/ar ...

  6. MySQL事务、锁机制、查询缓存

    MySQL事务 何为事务? 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit). 一个事务可以是一条SQL语句,一组SQL语句或整个程序. 事务的特性: 事 ...

  7. ASP.NET Core修改IOC为Autofac

    如下是我为了了解如何更换ASP.NET Core中的IOC而查找的文章,如果大家英文OK的,可以直接前往阅读,同时也已经有简单的github例子供大家参考. 参考文章: ASP.NET Core文档: ...

  8. Redis源码解析:24sentinel(五)TLIT模式、执行脚本

    十一:TILT模式 根据之前的介绍可知,哨兵的运行,非常依赖于系统时间,但是当系统时间被调整,或者哨兵中的流程因为某种原因(比如负载较高.IO发生阻塞.进程被信号停止等)而被阻塞时,哨兵的行为就会变得 ...

  9. ES6学习笔记之字符串的扩展

    字符串的for of ES6 为字符串添加了遍历器接口,使得字符串可以被for...of循环遍历. const str='abcd'; for(let s of str){ console.log(s ...

  10. Composer项目安装依赖包

    说明:一般用Composer的项目中,目录下都有一个composer.json文件,安装这些依赖,只需要输入命令即可 步骤: cmd进入项目目录,运行命令即可 composer install 文章参 ...