搞程序的是不是都熬夜的呢?我是的,不过很快就会努力不是了.为了健康,做一个不熬夜的程序员
本来打算了5:00睡的,鬼使神差莫明其妙地放下了PHP写了点C++,于是就有了以下代码的产生,也许是太久没有写C++了.
关于算法我已经写在程序的注释里了.简言之是先相加(不管进位),最后一起进位.
//
$Id: multi.cpp 6 2006-11-01 21:12:48Z JiangMiao $
// JiangMiao's Blog http://blog.csdn.net/antter
#include " stdafx.h "
#include < iostream >
#include < string >
using namespace std;
/// 转换字符串为
char * strToInt( const string & in )
{
char * rt = new char [ in .size()];
for (size_t i = 0 ;i < in .size();i ++ )
{
rt[i] = in [i] - ' 0 ' ;
}
return rt;
}
/* *
* 大数相乘,最大位数 0.04G 即32位int/(9*9)
*/
string mul( const string & sa, const string & sb)
{
string rt;
size_t la = sa.size();
size_t lb = sb.size();
size_t lr = la + lb; // 最大可能位数
char * a = strToInt(sa);
char * b = strToInt(sb);
unsigned int * r = new unsigned int [lr]; // 分配结果空间
size_t ia,ib,ir;
rt.reserve(lr);
memset(r, 0 ,lr * sizeof ( int ));
for (ia = 0 ;ia < la;ia ++ ) // 相乘
{
for (ib = 0 ;ib < lb;ib ++ )
{
ir = ib + ia + 1 ;
r[ir] += a[ia] * b[ib];
}
}
for (ir = lr - 1 ;ir > 0 ;ir -- ) // 进位
{
int add = r[ir] / 10 ;
r[ir - 1 ] += add;
r[ir] %= 10 ;
}
for (ir = 0 ;ir < lr;ir ++ ) // 除去前面多余的0
{
if (r[ir] != 0 )
break ;
}
for (;ir < lr;ir ++ ) // 生成字串
{
rt.append( 1 ,r[ir] + ' 0 ' );
}
delete a;
delete b;
delete r;
return rt;
}
/*
提升性能的改进:
1. 使用char* 代替string
2. 多数相乘返回非string,最后由intToStr进行字串输出,可极大地节省预处理和生成的时间
实现以上两点性能提升至少45%,乱猜的 :)
*/
/// 以下为测试文件
#include " windows.h "
int main( int argc, char ** argv)
{
string rt;
LARGE_INTEGER fre,begin,end;
QueryPerformanceFrequency( & fre);
QueryPerformanceCounter( & begin);
// 10000阶乘测试
rt = " 1 " ;
for ( int i = 1 ;i <= 10000 ;i ++ )
{
char b[ 6 ];
_itoa_s(i,b, 10 );
rt = mul(rt,b);
}
QueryPerformanceCounter( & end);
cout << " Spend " << (end.QuadPart - begin.QuadPart) * 1000000 / fre.QuadPart << " ns " << endl;
cout << rt.size() << endl;
// cout<<rt<<endl;
return 0 ;
}
/* 测试10000!的结果
* C4 2.66MHZ
Spend 16911238ns //17s
35660.
*/
// JiangMiao's Blog http://blog.csdn.net/antter
#include " stdafx.h "
#include < iostream >
#include < string >
using namespace std;
/// 转换字符串为
char * strToInt( const string & in )
{
char * rt = new char [ in .size()];
for (size_t i = 0 ;i < in .size();i ++ )
{
rt[i] = in [i] - ' 0 ' ;
}
return rt;
}
/* *
* 大数相乘,最大位数 0.04G 即32位int/(9*9)
*/
string mul( const string & sa, const string & sb)
{
string rt;
size_t la = sa.size();
size_t lb = sb.size();
size_t lr = la + lb; // 最大可能位数
char * a = strToInt(sa);
char * b = strToInt(sb);
unsigned int * r = new unsigned int [lr]; // 分配结果空间
size_t ia,ib,ir;
rt.reserve(lr);
memset(r, 0 ,lr * sizeof ( int ));
for (ia = 0 ;ia < la;ia ++ ) // 相乘
{
for (ib = 0 ;ib < lb;ib ++ )
{
ir = ib + ia + 1 ;
r[ir] += a[ia] * b[ib];
}
}
for (ir = lr - 1 ;ir > 0 ;ir -- ) // 进位
{
int add = r[ir] / 10 ;
r[ir - 1 ] += add;
r[ir] %= 10 ;
}
for (ir = 0 ;ir < lr;ir ++ ) // 除去前面多余的0
{
if (r[ir] != 0 )
break ;
}
for (;ir < lr;ir ++ ) // 生成字串
{
rt.append( 1 ,r[ir] + ' 0 ' );
}
delete a;
delete b;
delete r;
return rt;
}
/*
提升性能的改进:
1. 使用char* 代替string
2. 多数相乘返回非string,最后由intToStr进行字串输出,可极大地节省预处理和生成的时间
实现以上两点性能提升至少45%,乱猜的 :)
*/
/// 以下为测试文件
#include " windows.h "
int main( int argc, char ** argv)
{
string rt;
LARGE_INTEGER fre,begin,end;
QueryPerformanceFrequency( & fre);
QueryPerformanceCounter( & begin);
// 10000阶乘测试
rt = " 1 " ;
for ( int i = 1 ;i <= 10000 ;i ++ )
{
char b[ 6 ];
_itoa_s(i,b, 10 );
rt = mul(rt,b);
}
QueryPerformanceCounter( & end);
cout << " Spend " << (end.QuadPart - begin.QuadPart) * 1000000 / fre.QuadPart << " ns " << endl;
cout << rt.size() << endl;
// cout<<rt<<endl;
return 0 ;
}
/* 测试10000!的结果
* C4 2.66MHZ
Spend 16911238ns //17s
35660.
*/
欢迎探讨.我的Blog是 http://blog.csdn.net/antter