读书人

小弟我写的N阶层算法大家来挑刺

发布时间: 2012-02-21 16:26:23 作者: rapoo

我写的N阶层算法,大家来挑刺
因为要考虑值溢出的问题,所以用了链表(直接用了STL list),思路大概如下:
把一个整形值存在list中,按照个、十、百拆开,begin为最高位,end为个位数。
于是做list和list的乘积,把值存放在另一个list中,通过嵌套完成N的阶层。

大家看看有哪些地方写的不好,欢迎指正、砸砖、鄙视,多谢!

#include <exception>
#include <iostream>
#include <list>
typedef unsigned char Odd;
typedef unsigned char BYTE;
typedef std::list <Odd> OddList;
typedef OddList::iterator OddListIter;
typedef OddList::const_iterator OddListConstIter;
typedef OddList::reverse_iterator RvsOddListIter;
typedef OddList::const_reverse_iterator RvsOddListConstIter;
inline void getList(OddList& oddLst, unsigned long n)
{
unsigned long val = n;
oddLst.clear();
while(val > 10)
{
Odd m = val % 10;
val = val/10;
oddLst.push_front(m);
}
oddLst.push_front(val);
}
inline void plusList(OddList& left, const OddList& right)
{

RvsOddListIter iL = left.rbegin();
RvsOddListConstIter iR = right.rbegin();
Odd m = 0;
Odd n = 0;
while(iL != left.rend() && iR !=right.rend())
{
BYTE value = (*iL) + (*iR) + n;
m = value % 10;
n = value /10;
(*iL) = m;
++iL;
++iR;
}
if(left.size() > right.size())
{
while(iL != left.rend())
{
BYTE value = (*iL) + n;
m = value % 10;
n = value /10;
(*iL) = m;
++iL;
}
}
if(left.size() < right.size())
{


while(iR != right.rend())
{
BYTE value = (*iR) + n;
m = value % 10;
n = value /10;
left.push_front(m);
++iR;
}
}
if(n!=0)
{
left.push_front(n);
}
}
inline void multiPlyOdd(OddList& left, const Odd odd)
{
if(odd == 0)
{
left.clear();
return;
}
Odd m = 0;
Odd n = 0;
for(RvsOddListIter iL = left.rbegin(); iL != left.rend(); ++iL)
{
BYTE value = odd * (*iL) + n;
m = value % 10;
n = value / 10;
(*iL) = m;
}
if(n != 0)
{
left.push_front(n);
}
}
inline void multiPlyList(OddList& left, const OddList& right)
{
if(left.empty() || right.empty())
{
return;
}
OddList leftOff = left;
RvsOddListConstIter iR = right.rbegin();
multiPlyOdd(left, *iR);
++iR;
while(iR != right.rend())
{
leftOff.push_back(0);
OddList tmp = leftOff;
multiPlyOdd(tmp, *iR);
plusList(left, tmp);
++iR;
}
}
inline void caluFactorialLoop(OddList& oddLst, unsigned long n)


{
if(n < 2)
{
return;
}
OddList right;
getList(right, n);
multiPlyList(oddLst, right);
std::cout < < "....... " < < n < < ".. ok .. " < < std::endl;
caluFactorialLoop(oddLst, n - 1);
}
inline void caluFactorial(OddList& oddLst, unsigned long n)
{
getList(oddLst, n);
std::cout < < "....... " < < n < < ".. ok .. " < < std::endl;
caluFactorialLoop(oddLst, n - 1);
}
inline void print(const OddList& rst)
{
std::cout < < "length: " < < rst.size() < < std::endl;
OddListConstIter iter = rst.begin();
while(iter != rst.end())
{
std::cout < < (short)*iter;
iter++;
}
std::cout < < std::endl;
}

int main()
{
while(1)
{
unsigned long n;
std::cout < < "Please input the num: ";
std::cin > > n;
if(0 == n)
{
break;
}
OddList oddLst;
caluFactorial(oddLst, n);
print(oddLst);
}
return 0;


[解决办法]
按照个、十、百拆开
=========
可以考虑 3位一起存放,就是 个十百三位保存在一个元素中,
后面类似处理。。。
[解决办法]
函数普遍应用inline是多余,关于inline是否必要,编译器会自行决定,甚至一些编译器完全是忽略用户显示的inline,所以这些都是不必要的,一般对interface函数进行显示要求inline,功能性长函数不要~
[解决办法]
总体结构上可以选择包装成累,将plus变成operator+
其它类似,这样有利于保存大数为私有成员,没有道理C++ style的东西还沿用C style的function + data分开的原则,包装大数可以更好得保存细节

其次,某些地方可能效率欠佳,整体效率也欠佳,如:
while(iter != rst.end())
应当保存rst.end()而不是每次都再取值

读书人网 >C++

热点推荐