stl的string,vector,map问题,求优化啊
/**一个全球IP地址文库(ipaddr_utf8.txt),其中保存了全球IP地址段信息和其对应的位置信息。每行数据格式为:起始IP终止IPIP位置信息读取文件实现以下...
/*
* 一个全球IP地址文库(ipaddr_utf8.txt),其中保存了全球IP地址段信息和其对应的位置信息。
每行数据格式为: 起始IP 终止IP IP位置信息
读取文件实现以下功能(要求只读一次就可以完成下面的两个功能)
1,对IP位置进行统计,并输出统计结果(输出到文件)
格式如下:
ip位置信息\tIP段的个数\n
2,输出包含用户指定字符串的ip位置信息(输出到屏幕)
ip位置信息\tip段的个数\n
\t起始ip\t终止Ip\n
\t起始ip\t终止Ip\n
.........
如这种
062.144.212.000 062.144.212.079 奥地利
总共包含“用户指定的字符串”的ip位置信息xxx条,其中ip段xxx条
*/
#include <iostream>
#include <cstdlib>
#include <vector>
#include <map>
#include <string>
#include <fstream>
using namespace std;
//将每条记录分割成字符串
vector<string> split(string text)
{
char str[256];
int s;
vector<string> vec;
strcpy(str,text.c_str());
char *p;
p=strtok(str," ");
vec.push_back(p);
p=strtok(NULL," ");
vec.push_back(p);
int len=strlen(p);
while(*p!='\0')
{
++p;
}
p++;
while(*p==32)
{
p++;
}
vec.push_back(p);
return rec;
}
int main()
{
string s,filename="/home/ipaddr_utf8.txt";
vector<string> vec1;
vector<string> vec3;
vector<string> vec4;
map<string,int> m1;
map<string,string> m2;
int num;
ifstream infile(filename.c_str());
if(!infile)
{
cout<<"error opening file"<<endl;
return -1;
}
while(getline(infile,s))
{
vec1=split(s);//存放分割后个段字符串
vec3.push_back(vec1[2]);//存储ip位置信息
m2.insert(pair<string>(("\t"+vec1[0]+"\t"+vec1[1]+"\n"),vec1[2]));//ip地址段
}
//迭代器
vector<string>::iterator iter=vec3.begin();
for(;iter!=vec3.end();iter++)
{
num=0;
//这里用来判断是否已经对某个位置判断过数量,如果判断过,跳出循环。
vector<string>::iterator iter4=find(vec4.begin(),vec4.end(),*iter);
if(iter4!=vec4.end())
{
continue;
}
vec4.push_back(*iter);
//计算某个位置的次数
//主要消耗时间的就是这里
num=count(vec3.begin(),vec3.end(),*iter);
cout<<*iter<<endl;
//保存ip位置以及这个位置的ip地址段数量
m1.insert(pair<string,int>(*iter,num));
}
map<string,int>::iterator iter3=m1.begin();
while(iter3!=m1.end())
{
cout<<iter3->first<<"\t"<<iter3->second<<endl;
iter3++;
}
//输出包含用户指定字符串的位置信息,入指定内蒙古,就输出所有和内蒙古有关的IP位置信息。
char str_se[]="内蒙古";
int r;
map<string,int>::iterator iter4=m1.begin();
while(iter4!=m1.end())
{
if((iter4->first).find(str_se,0)!=-1)
{
cout<<iter4->first<<"\t"<<iter4->second<<endl;
map<string,string>::iterator iter5=m2.begin();
while(iter5!=m2.end())
{
if((iter4->first)==(iter5->second))
{
cout<<iter5->first<<endl;
}
iter5++;
}
}
iter4++;
}
infile.close();
infile.clear();
return 0;
}
这个是40w行的记录,txt文件,要求5分钟读完。可我这个程序,功能是能实现,可是时间太长。求高手给优化啊。 展开
* 一个全球IP地址文库(ipaddr_utf8.txt),其中保存了全球IP地址段信息和其对应的位置信息。
每行数据格式为: 起始IP 终止IP IP位置信息
读取文件实现以下功能(要求只读一次就可以完成下面的两个功能)
1,对IP位置进行统计,并输出统计结果(输出到文件)
格式如下:
ip位置信息\tIP段的个数\n
2,输出包含用户指定字符串的ip位置信息(输出到屏幕)
ip位置信息\tip段的个数\n
\t起始ip\t终止Ip\n
\t起始ip\t终止Ip\n
.........
如这种
062.144.212.000 062.144.212.079 奥地利
总共包含“用户指定的字符串”的ip位置信息xxx条,其中ip段xxx条
*/
#include <iostream>
#include <cstdlib>
#include <vector>
#include <map>
#include <string>
#include <fstream>
using namespace std;
//将每条记录分割成字符串
vector<string> split(string text)
{
char str[256];
int s;
vector<string> vec;
strcpy(str,text.c_str());
char *p;
p=strtok(str," ");
vec.push_back(p);
p=strtok(NULL," ");
vec.push_back(p);
int len=strlen(p);
while(*p!='\0')
{
++p;
}
p++;
while(*p==32)
{
p++;
}
vec.push_back(p);
return rec;
}
int main()
{
string s,filename="/home/ipaddr_utf8.txt";
vector<string> vec1;
vector<string> vec3;
vector<string> vec4;
map<string,int> m1;
map<string,string> m2;
int num;
ifstream infile(filename.c_str());
if(!infile)
{
cout<<"error opening file"<<endl;
return -1;
}
while(getline(infile,s))
{
vec1=split(s);//存放分割后个段字符串
vec3.push_back(vec1[2]);//存储ip位置信息
m2.insert(pair<string>(("\t"+vec1[0]+"\t"+vec1[1]+"\n"),vec1[2]));//ip地址段
}
//迭代器
vector<string>::iterator iter=vec3.begin();
for(;iter!=vec3.end();iter++)
{
num=0;
//这里用来判断是否已经对某个位置判断过数量,如果判断过,跳出循环。
vector<string>::iterator iter4=find(vec4.begin(),vec4.end(),*iter);
if(iter4!=vec4.end())
{
continue;
}
vec4.push_back(*iter);
//计算某个位置的次数
//主要消耗时间的就是这里
num=count(vec3.begin(),vec3.end(),*iter);
cout<<*iter<<endl;
//保存ip位置以及这个位置的ip地址段数量
m1.insert(pair<string,int>(*iter,num));
}
map<string,int>::iterator iter3=m1.begin();
while(iter3!=m1.end())
{
cout<<iter3->first<<"\t"<<iter3->second<<endl;
iter3++;
}
//输出包含用户指定字符串的位置信息,入指定内蒙古,就输出所有和内蒙古有关的IP位置信息。
char str_se[]="内蒙古";
int r;
map<string,int>::iterator iter4=m1.begin();
while(iter4!=m1.end())
{
if((iter4->first).find(str_se,0)!=-1)
{
cout<<iter4->first<<"\t"<<iter4->second<<endl;
map<string,string>::iterator iter5=m2.begin();
while(iter5!=m2.end())
{
if((iter4->first)==(iter5->second))
{
cout<<iter5->first<<endl;
}
iter5++;
}
}
iter4++;
}
infile.close();
infile.clear();
return 0;
}
这个是40w行的记录,txt文件,要求5分钟读完。可我这个程序,功能是能实现,可是时间太长。求高手给优化啊。 展开
1个回答
展开全部
大概看了下,发现你对C++的了解和使用还欠缺很多。
整段代码各种很低效的写法,比如split函数按值返回一个vector,这将引起两次vector全量拷贝,是极大的浪费,参数用的是按值传递而不是按const引用传递,等等。字符串操作混用C和C++的处理方式,一会用string一会又用char数组,等等。都是很不好的习惯。另外还用了C++中的stream,但C++中的stream效率不如C中的FILE。
另外你的编码风格也不太好,变量名没有任何含义,别人看得时候很难理解。
上述都是一些写法习惯问题,你这个代码从算法角度上说也是很低效的。
你为什么要在循环中每次遍历一遍vec3呢?仅仅只是为了count一下,为何不在一开始那个while循环里面就count好呢?这样你整个程序都只需要遍历一遍vec3就行了啊,时间复杂度马上降低一个量级。
还有你那个vec4,也是很不合适的用法。从你的代码来看,你的vec4只是为了做一个重复性检测,为什么要用vector呢?这种时候显然用set更好啊,在vector里查找是很慢的,时间复杂度O(n)啊,set里查找一个元素只需要O(logn),快一个级别。
感觉你对STL里面的标准容器的认识还欠缺很多,没有搞清楚这些容器的适用场合。还是需要多补补基础啊。
整段代码各种很低效的写法,比如split函数按值返回一个vector,这将引起两次vector全量拷贝,是极大的浪费,参数用的是按值传递而不是按const引用传递,等等。字符串操作混用C和C++的处理方式,一会用string一会又用char数组,等等。都是很不好的习惯。另外还用了C++中的stream,但C++中的stream效率不如C中的FILE。
另外你的编码风格也不太好,变量名没有任何含义,别人看得时候很难理解。
上述都是一些写法习惯问题,你这个代码从算法角度上说也是很低效的。
你为什么要在循环中每次遍历一遍vec3呢?仅仅只是为了count一下,为何不在一开始那个while循环里面就count好呢?这样你整个程序都只需要遍历一遍vec3就行了啊,时间复杂度马上降低一个量级。
还有你那个vec4,也是很不合适的用法。从你的代码来看,你的vec4只是为了做一个重复性检测,为什么要用vector呢?这种时候显然用set更好啊,在vector里查找是很慢的,时间复杂度O(n)啊,set里查找一个元素只需要O(logn),快一个级别。
感觉你对STL里面的标准容器的认识还欠缺很多,没有搞清楚这些容器的适用场合。还是需要多补补基础啊。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询