同一问题的两种不同解法 : MFC8.0 与 C++ 标准库
来源:互联网 发布:0基础如何成为程序员 编辑:程序博客网 时间:2024/06/05 05:11
前两天写了一个对40M的有格式文本文件的信息抽取,开始使用 MFC的CFile来读取,存储到char*中,然后对每个字符循环读取,判断抽取有用信息.思路很简单,也很笨拙,所以也就没有奢望它的效率好到那里.但实际运行的时候还是非常令人吃惊,两个多小时竟然没有跑完; 又细看了一下代码,只做简单的优化是没有用处了,就改用了C++来重新写,fstream的标准库,string 做为buffer,又调用了string的一些方法,结果非常的好,用了30多秒,就跑完了. 现把代码贴出来 ,达人多指教.
文本文件是按行组织的,每一行的数据以空格分割,共44维数据,每一维是 Key:value的格式.现在要取出其中的 qid,1,13...等几维数据,每行的前后的信息也要保留.
0 qid:1 1:11.512826 2:288.000000 3:195.000000 4:6.000000 5:2.000000 6:0.223063 7:0.000858 8:0.000677 9:0.000018 10:0.000826 11:0.001129 12:0.003413 13:10.546871 14:0.000772 15:-14.725600 16:0.017391 17:-12.865100 18:-9.148330 19:-8.108850 20:0.569967 21:-8.119490 22:-7.974970 23:-7.379150 24:1.563410 25:-7.253540 26:-7.252590 27:10.546905 28:2.000000 29:0.000000 30:0.000000 31:0.000000 32:0.000035 33:0.000000 34:0.000000 35:0.000000 36:0.000249 37:0.143097 38:0.000607 39:0.004101 40:0.001772 41:0.001124 42:19.575701 43:12.622301 44:11.723003 #docid = 1032
第一种写法:
第二种写法:
#include "stdafx.h"
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
using namespace std;
/*---------------------------------------------------------------------------
进取维数部分
-----------------------------------------------------------------------------*/
const string token(",1,qid,13,27,28,39,40,41,42,43,44,");
const int NUM=15;
//qid,1,13,27,28,39,40,41,42,43,44
inline bool IsIn(string sbuf){
sbuf.push_back(',');
sbuf.insert(0,",");
if (token.find(sbuf)!=string::npos)
return true;
else
return false;
}
/*
name:Extracotr
function:从原始数据中提到指定的几维
提取的维数定义在 token中
*/
void Extractor(){
string ifile("d:/TD2003.txt");
cout << "please input file to extract:"<<endl;
//cin>>ifile;
ifstream infile(ifile.c_str() );
string ofile("d:/TD03.txt");
cout<<"please input the file to save as:"<<endl;
//cin>>ofile;
ofstream outfile(ofile.c_str());
string buf,sbuf;
//while(getline(infile,buf,' ')){
// outfile<<' ';
//}
int enter(1);
string::size_type pos;
while( infile>>buf ){
pos=buf.find(':');
if (pos==string::npos)
outfile<<buf<<(enter++ % NUM? " ":" ");
else
{
//buf.copy(sbuf,pos);
sbuf=buf.substr(0,pos);
if (IsIn(sbuf))
outfile<<buf<<(enter++ % NUM? " ":" ");
}
}
infile.close();
outfile.close();
}
文本文件是按行组织的,每一行的数据以空格分割,共44维数据,每一维是 Key:value的格式.现在要取出其中的 qid,1,13...等几维数据,每行的前后的信息也要保留.
0 qid:1 1:11.512826 2:288.000000 3:195.000000 4:6.000000 5:2.000000 6:0.223063 7:0.000858 8:0.000677 9:0.000018 10:0.000826 11:0.001129 12:0.003413 13:10.546871 14:0.000772 15:-14.725600 16:0.017391 17:-12.865100 18:-9.148330 19:-8.108850 20:0.569967 21:-8.119490 22:-7.974970 23:-7.379150 24:1.563410 25:-7.253540 26:-7.252590 27:10.546905 28:2.000000 29:0.000000 30:0.000000 31:0.000000 32:0.000035 33:0.000000 34:0.000000 35:0.000000 36:0.000249 37:0.143097 38:0.000607 39:0.004101 40:0.001772 41:0.001124 42:19.575701 43:12.622301 44:11.723003 #docid = 1032
第一种写法:
CExtractKeysDlg::CExtractKeysDlg(CWnd* pParent /*=NULL*/)
: CDialog(CExtractKeysDlg::IDD, pParent)
, openfileedit(_T(""))
, savefileedit(_T(""))
, saveDim(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
openfileedit="d:/d.txt";
savefileedit="d:/e.txt";
saveDim="qid,1,13,27,28,39,40,41,42,43,44";
//UpdateData(false);
}
void CExtractKeysDlg::OnBnClickedExtract()
{
// TODO: 在此添加控件通知处理程序代码
const int readlen=1024*64; //读取64k大的文件
char buf[readlen],wbuf[readlen];
int truelen(0),wlen(0);
int wflag(1);//记录需要写入几次的标志
UpdateData(true);
CFile cfopen(this->openfileedit,CFile::modeRead);
CFile cfsave(this->savefileedit,CFile::modeCreate|CFile::modeWrite);
do{
truelen=cfopen.Read(buf,readlen);
int i(0),wbegin(0),wend(0),lastspace(0),wlast(0);
for(;i<truelen;i++){
switch(buf[i]){
case ' ': //记录空格位置,完成写任务
lastspace=i;
if(wflag){
wflag--;
wend=lastspace-1;
ArrayPut(buf,wbuf,wbegin,wend,wlast);
if (wflag) wbegin=i;
}
break;
case ':': //检测,置写标记
if (IsIn(buf,lastspace+1,i-1)){
wflag++;
wbegin=lastspace;
}
break;
case 10: //换行之前的要写入
if(wflag){
wend=i;
ArrayPut(buf,wbuf,wbegin,wend,wlast);
wbegin=i+1;
}
break;
case '#': //docid默认写入
wflag += 3;
wbegin=i-1;
break;
}//switch
}//for
if(wflag && wend>=wbegin) ArrayPut(buf,wbuf,wbegin,wend,wlast);
if(!wflag){
cfopen.Seek(lastspace-truelen,CFile::current);
}
cfsave.Write(wbuf,wlast);
//cfsave.Flush(); //先在内存中缓存,到一定数量再到文件中.
}while(truelen==readlen);
cfopen.Close();
cfsave.Close();
//优化二,把几个小函数声明为内联函数,减小运行代价.
}
inline bool CExtractKeysDlg::ArrayPut(const char* src,char * dst,int begin,int end,int &lastpos)
{
//return false;
for(;begin<=end;begin++)
dst[lastpos++]=src[begin];
return true;
}
inline bool CExtractKeysDlg::IsIn(const char* buf,int begin,int end)
{
CString substr(',');
saveDim.Insert(0,',');
saveDim.AppendChar(',');
int sub(1);
for(;begin<=end;begin++)
substr.AppendChar(buf[begin]);
substr.AppendChar(',');
if (saveDim.Find(substr)<0)
return false;
else
return true;
}
: CDialog(CExtractKeysDlg::IDD, pParent)
, openfileedit(_T(""))
, savefileedit(_T(""))
, saveDim(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
openfileedit="d:/d.txt";
savefileedit="d:/e.txt";
saveDim="qid,1,13,27,28,39,40,41,42,43,44";
//UpdateData(false);
}
void CExtractKeysDlg::OnBnClickedExtract()
{
// TODO: 在此添加控件通知处理程序代码
const int readlen=1024*64; //读取64k大的文件
char buf[readlen],wbuf[readlen];
int truelen(0),wlen(0);
int wflag(1);//记录需要写入几次的标志
UpdateData(true);
CFile cfopen(this->openfileedit,CFile::modeRead);
CFile cfsave(this->savefileedit,CFile::modeCreate|CFile::modeWrite);
do{
truelen=cfopen.Read(buf,readlen);
int i(0),wbegin(0),wend(0),lastspace(0),wlast(0);
for(;i<truelen;i++){
switch(buf[i]){
case ' ': //记录空格位置,完成写任务
lastspace=i;
if(wflag){
wflag--;
wend=lastspace-1;
ArrayPut(buf,wbuf,wbegin,wend,wlast);
if (wflag) wbegin=i;
}
break;
case ':': //检测,置写标记
if (IsIn(buf,lastspace+1,i-1)){
wflag++;
wbegin=lastspace;
}
break;
case 10: //换行之前的要写入
if(wflag){
wend=i;
ArrayPut(buf,wbuf,wbegin,wend,wlast);
wbegin=i+1;
}
break;
case '#': //docid默认写入
wflag += 3;
wbegin=i-1;
break;
}//switch
}//for
if(wflag && wend>=wbegin) ArrayPut(buf,wbuf,wbegin,wend,wlast);
if(!wflag){
cfopen.Seek(lastspace-truelen,CFile::current);
}
cfsave.Write(wbuf,wlast);
//cfsave.Flush(); //先在内存中缓存,到一定数量再到文件中.
}while(truelen==readlen);
cfopen.Close();
cfsave.Close();
//优化二,把几个小函数声明为内联函数,减小运行代价.
}
inline bool CExtractKeysDlg::ArrayPut(const char* src,char * dst,int begin,int end,int &lastpos)
{
//return false;
for(;begin<=end;begin++)
dst[lastpos++]=src[begin];
return true;
}
inline bool CExtractKeysDlg::IsIn(const char* buf,int begin,int end)
{
CString substr(',');
saveDim.Insert(0,',');
saveDim.AppendChar(',');
int sub(1);
for(;begin<=end;begin++)
substr.AppendChar(buf[begin]);
substr.AppendChar(',');
if (saveDim.Find(substr)<0)
return false;
else
return true;
}
#include "stdafx.h"
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
using namespace std;
/*---------------------------------------------------------------------------
进取维数部分
-----------------------------------------------------------------------------*/
const string token(",1,qid,13,27,28,39,40,41,42,43,44,");
const int NUM=15;
//qid,1,13,27,28,39,40,41,42,43,44
inline bool IsIn(string sbuf){
sbuf.push_back(',');
sbuf.insert(0,",");
if (token.find(sbuf)!=string::npos)
return true;
else
return false;
}
/*
name:Extracotr
function:从原始数据中提到指定的几维
提取的维数定义在 token中
*/
void Extractor(){
string ifile("d:/TD2003.txt");
cout << "please input file to extract:"<<endl;
//cin>>ifile;
ifstream infile(ifile.c_str() );
string ofile("d:/TD03.txt");
cout<<"please input the file to save as:"<<endl;
//cin>>ofile;
ofstream outfile(ofile.c_str());
string buf,sbuf;
//while(getline(infile,buf,' ')){
// outfile<<' ';
//}
int enter(1);
string::size_type pos;
while( infile>>buf ){
pos=buf.find(':');
if (pos==string::npos)
outfile<<buf<<(enter++ % NUM? " ":" ");
else
{
//buf.copy(sbuf,pos);
sbuf=buf.substr(0,pos);
if (IsIn(sbuf))
outfile<<buf<<(enter++ % NUM? " ":" ");
}
}
infile.close();
outfile.close();
}
- 同一问题的两种不同解法 : MFC8.0 与 C++ 标准库
- poj1157(两种不同的解法)
- 同一问题的递归与动态规划解法
- [Wikioi 1295]N皇后问题---两种不同的解法(复习)
- 0-1背包问题的几种不同解法
- [Wikioi 1220]数字三角形---两种不同的解法(复习)
- [Wikioi 1294]全排列---两种不同的解法(复习)
- 八皇后问题的两种解法
- LCA问题的两种解法
- 汉诺塔问题的两种解法
- 八皇后问题的两种解法
- 8皇后问题的两种解法
- 八皇后问题的两种解法
- 约瑟夫问题--两种解法
- C语言求素数的不同解法
- 装配线(工作站)问题的两种解法
- 硬币兑换问题的两种解法之比较
- 01背包类型问题的两种解法
- 解决WEB开发中的中文问题(详细,有效)
- 经典网址
- 在Hibernate中配置Proxool连接池
- java工厂模式
- VS2003下制作数据库安装包
- 同一问题的两种不同解法 : MFC8.0 与 C++ 标准库
- 了解Hibernate的FlushMode.NEVER模式
- 软件需求文档范例
- SWT 界面时钟显示
- Linux指令篇:文件系统--mount
- Linux的内核启动参数
- (原创)我的初恋故事
- 存储过程(二)
- 引入控件以及注册控件的错误