读书人

sort()速度太慢高分求解解决方法

发布时间: 2012-03-17 19:06:28 作者: rapoo

sort()速度太慢,高分求解
typedef vector <CString> STRLST;
STRLST vecstr;
int n = 0, i = 1;
//char c_cha[_MAX_PATH];

CString s, str;
CStdioFile file;
file.Open( "d:\\联众.txt ",CFile::modeReadWrite | CFile::typeText|CFile::shareDenyRead );
while (file.ReadString(s))
{
s.MakeLower();//转为小写全部
//strncpy(c_cha,(LPCTSTR)s,sizeof(c_cha));
//vecstr.push_back(ToLow(c_cha));
vecstr.push_back(s);
i++;
}
//str.Format( "%d ", i);
str.Format( "%d ", vecstr.size()+1);
MessageBox(str, NULL, MB_OK);
//::std::sort(vecstr.begin(), vecstr.end(), compare); //这里慢
sort(vecstr.begin(), vecstr.end()); //这里慢


=================================================================
我对2万多行数据排序,用30到40多秒才完成;
是否要自己写比较函数才行?


[解决办法]
因为sort交换时是值拷贝,所以会很慢(赋值很多次,每次都可能在CStirng的内部动态分配内存)。
建议用vector <CString*> ,然后自己写比较函数:

bool compare_str(CString* left, CString* right)
{
return *left < *right;
}
[解决办法]
vecstr.push_back(&s);
===============================
估计是这里错了.

你直接申请CString*,保存入指针的值吧
[解决办法]
CWinApp theApp;

using namespace std;

#include <vector>
#include <afx.h>
#include <algorithm>
using namespace std;
struct cmp
{
bool operator()(const CString* l,const CString* r)
{
return (*l) <(*r);
}
};

struct out
{
void operator()(const CString *l)
{
cout < <(const char*)(*l) < <endl;
}
};

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
vector <CString*> v;
v.push_back(new CString( "444 ") );
v.push_back(new CString( "3333 ") );
v.push_back(new CString( "445 ") );
v.push_back(new CString( "33 ") );
v.push_back(new CString( "111 ") );
v.push_back(new CString( "666 ") );
v.push_back(new CString( "99 ") );

for_each(v.begin(),v.end(),out());
sort( v.begin(),v.end() , cmp() );
cout < <endl;
for_each(v.begin(),v.end(),out());
return 0;
}
[解决办法]
vecstr.push_back(&s); 改成
vecstr.push_back(new CString(s));

file.WriteString((LPCSTR)vecstr[n]); 改成
file.WriteString((LPCSTR)(*vecstr[n]));

最后要释放内存:
for (STRLST::iterator i = vecstr.begin(); i != vecstr.end(); i++)
delete *i;
vecstr.clear();


[解决办法]
> > 我对2万多行数据排序,用30到40多秒才完成;
> > 是否要自己写比较函数才行?

一、首先请确定你的这次排序结果是正确的。
二、请统计下字符串的平均长度。

[解决办法]
从效率的角度来讲,最好的是申请一块和文件大小一样大的内存,然后把所有 '\n '都替换成 '\0 ',再转换大小写,让vector里的内容指向大块内存中的字符串,最后应用快速排序,比几万次的内存分配干净多了。
但我想这里根本没必要使用这种优化。

[解决办法]
字符串我估计也不会慢到哪里去的
那个.NET的类库设计得很好的
我看里面有一个TrySZSort()的方法,是排序里面最关键的方法,要是你能把这个方法找找到,分析一下,肯定.....


我反汇编.NET的类库,至今没有找到那个extren方法,不知道他指向哪里了.....
[解决办法]
可能是MFC的CString和stl兼容性问题 用std::string/std::wstring试一下

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <iterator>

using namespace std;

int main() {
vector <string> coll;
coll.reserve(15000);
copy(istream_iterator <string> (cin), istream_iterator <string> (), back_inserter(coll));

sort(coll.begin(), coll.end());
unique_copy(coll.begin(), coll.end(), ostream_iterator <string> (cout, "\n "));
}

运行测试如下(是在一台Linux虚拟机上做的测试):
$ man gcc | ./sortvec | wc -l
11070
$ time man gcc | ./sortvec | wc -l
11070

real 0m2.664s
user 0m1.012s
sys 0m1.376s
[解决办法]
做一下变换,
应该使字符串copy的缘故。


另外如果实在不行,现把所有字符串补成32位对齐数据
重写compare
字符串比较改成整数串比较。

bool compare_str(CString* left, CString* right)
{
int comp =0;
int *p1=left;
int *p2= right;
if(*p1 <*p2)return -1;
else if(*p1> *p2) return 1;
else return compare_str(p1+4,p2+4);
}
,如果首子串重复比较多的话,那么把递归去掉,用循环代替就可以了。
由于我没有遇到这个问题,具体结果不知

读书人网 >C++

热点推荐