利用哈希表实现11位电话号码的快速排序
来源:互联网 发布:windows输错密码锁定 编辑:程序博客网 时间:2024/04/28 12:41
1 问题提出
设一个文件包含10亿条数据,其中每一条数据都是一个13开头的11位移动电话号码,且电话号码不重复,请用尽可能小的内存空间,将这些整数按升序进行排列,要求排序算法的时间复杂度为O(n)。
2 求解思路
难点包括两方面:时间复杂度和空间复杂度
1)时间复杂度:如果通过比较关键值(元素,电话号码)来排序,较快的算法时间复杂度也为O(nlogn),但是要求为O(n)。
2)空间复杂度,一条电话号码长度为11,10亿条大概需要4G内存,如何利用更小的内存来解决这个问题
方法:
可以使用位串数组的方式,来构造散列表,即如果某一电话号码存在可以令该电话号码为位串数组下标,并将相应位串元素置1。
算法实现步骤:
1)构造一个空的散列表:unsigned char ch[125000000] = {0}
2) 编写insert_ele子函数,实现在位串中插入一个元素
3)读取电话号码存放的文件,并调用insert_ele子函数,生成位串散列表
4)读取散列表,将位串中值为1的元素转换成相应的电话号码,存入文件中
C++程序
主函数
#include<iostream>#include<stdlib.h>#include<fstream>#include"myatol.h"using namespace std;/*********************************************************//* 11位电话号码的排序,要求时间复杂度为O(n) *//* 利用位串实现,排序 *//*********************************************************/// 算法实现步骤:// 1)构造一个空的散列表:unsigned char ch[125000000] = {0}// 2) 编写insert_ele子函数,实现在位串中插入一个元素// 3)读取电话号码存放的文件,并调用insert_ele子函数,生成位串散列表// 4)读取散列表,将位串中值为1的元素转换成相应的电话号码,存入文件中/*********************************************************/void insert_ele(unsigned char ch[], long long elementary);void generate_hash(unsigned char ch[]);void sort_by_hash(unsigned char ch[]);void main(){ unsigned char ch[125000000] = {0}; generate_hash(ch);//从电话文件中读取电话号码,并置位位串相应位置的元素,构成哈希表 sort_by_hash(ch);//从位串中顺序读取已经排序好的电话号码到文件中 system("pause");}void insert_ele(unsigned char ch[],long long elementary){ int i = (elementary % 1000000000)/8; int j = elementary % 8; ch[i] = ch[i] | (0x01 << j); cout<<"ch[i]: "<<i<<endl; cout<<"ch[i][j]: "<<j<<endl;}void generate_hash(unsigned char ch[]){ char str[12]; ifstream in("data.txt"); while(! in.eof()) { in.getline(str,12,'\n'); cout << "str: "<<str <<endl; myatol a; long long b = a.myAtoll((str)); if(b) insert_ele(ch,b); cout<< "b: "<<b <<endl; } in.close();}void sort_by_hash(unsigned char ch[]){ ofstream out("data1.txt"); for(int i = 0;i < 125e6;i++) { for(int j = 0; j < 8;j++) { unsigned char n = 1; n = n << j; if((ch[i]&n)) { long long data = 13e9 + i*8 +j; out <<data<<endl; cout <<data<<endl; //cout<<i*8 +j<<endl; } } } out.close();}
头文件函数
#ifndef MYATOL_H_#define MYATOL_H_#include<iostream>using namespace std;class myatol{public: long long myAtoll(const char * str) { long long res = 0; int flag = 1; int i = 0; int count = 0; while(str[i] == ' ') i++; if(str[i] == '-') { flag = -1; i++; count++; } else if(str[i] == '+') { flag = 1; i++; count++;//当出现两个符号时,输出0 } if(count > 1) return 0; if(str[i]> '9' || str[i] < '0') { return 0; } int numcount = 0; for(;str[i];i++) { if( str[i] >='0' && str[i] <= '9') { numcount++; res = res * 10 +(str[i] - '0'); if(numcount > 12) { cout<<"数字超出上界"<<endl; break; } } } return res; }};#endif
阅读全文
1 0
- 利用哈希表实现11位电话号码的快速排序
- 随机生成11位的电话号码
- 电话号码的快速查找
- 快速排序思想的利用
- 利用OpenMP实现并行快速排序算法
- 利用c++模板实现快速排序
- 利用Python实现快速算法排序
- 利用qsort库函数实现快速排序
- 快速排序的实现
- 快速排序的实现
- 快速排序的实现
- 快速排序的实现
- 快速排序的实现
- 快速排序的实现
- 快速排序的实现
- 快速排序的实现
- 快速排序的实现
- 快速排序的实现
- Linux下源码安装PHP的GD支持库
- 如何提高阅读源代码能力
- HDU 6067 Big Integer(生成函数+NTT)
- servlet生命周期
- JAVA类集(1)简单操作
- 利用哈希表实现11位电话号码的快速排序
- Shell 命令行,写一个自动整理 ~/Downloads/ 文件夹下文件的脚本
- mybaits+mysql获取插入数据的主键
- Android中常见正则表达式总结
- 修改项目路径为tomcat路径
- 剑指offer--数字在排序数组中出现的次数
- P1541 乌龟棋
- 背包问题复习2
- TF-IDF与余弦相似性的应用(二):找出相似文章