a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 173|回复: 2

[C++] 2012年计算机等级考试二级C++辅导讲义(10)

[复制链接]
发表于 2012-7-31 21:56:58 | 显示全部楼层 |阅读模式
 大整数阶乘的算法思路   这里的大整数指大于500以上的整数,当然更大也可以。由于整数阶乘递增的很快,远大于指数式递增,对于小整数,比如20,30左右,可以直接使用比如递归的方式进行,这很基本。
' R* S" h& @* o  但是当整数较大时,阶乘的结果很大,远非一个int或者long就能存的下的,比如1000的阶乘结果有上千位。# s. f  @+ _: b
  所以大整数阶乘设计的关键点就是存储大整数,当选择了存储大整数,那么整数的乘法运算也不能再依靠*了,所以还要重新设计大整数的惩罚运算。
4 @+ f1 m0 k  ]- F7 S& p  B" m  上面是我的设计思路。网上找过相关的文章,有高手以4行代码完成了该算法,确实佩服!当然这涉及了算法的优化,不管那么多了,这里要的就是以尽量清晰地思路快速设计该算法,这是使用了STL标准库的容器。1 ^+ S" K$ Q, {) @- l2 K
  下面是我的算法代码,直接贴这里了,注意看相关的注释:/ k9 r" K. ]. H! q2 a. h; q
  #include
+ _1 S5 m+ l9 ~  #include. {. X& N/ T+ C8 w+ S
  using namespace std;
/ _: s1 f0 i4 ^" Z  // 传入整数:int,和整数-1的阶乘结果,进行相乘的结果
% M+ u+ M+ V0 \* w8 b  // 结构依然存储到容器中
' A( I: j6 X" l) ^  k( [# I  void Calc(int num,vector &calcresult)2 Y. q% E6 g$ s) X
  {
7 z/ |- s7 E( J( S3 R) P* @4 Q, a: t  vector tempnum;  L. i7 Q: M, i) i$ ~/ r
  vector rest;
+ D7 Y' W" F4 m( s' j  // 将传入的int拆分之后保存到容器中! a5 v9 d( C, n
  do
+ o; h* K5 a4 V3 u  {+ w; }2 Y# ]1 @% S' Z$ u
  tempnum.push_back(num % 10);# C2 O+ G# U* E, {" T
  num = num / 10;
6 @! E: ~" O2 F7 ?5 w5 u  z) P  } while (num);# @& u9 s3 ?) e
  // 将分拆之后的num进行乘法计算
4 G0 x2 C5 ]8 k, M- K
4 Q. W" M/ [$ S  J- S3 ~+ s3 O  unsigned int i = 0,j = 0;
回复

使用道具 举报

 楼主| 发表于 2012-7-31 21:56:59 | 显示全部楼层

2012年计算机等级考试二级C++辅导讲义(10)

</p>  for(i = 0;i < tempnum.size();++i)% Q# S8 N# t/ x5 n& D: F
  {) ~0 A$ c! q, J" E
  int carry = 0;// 存储每位计算时来自低位的进位
  c1 ?3 c# {+ t3 L  for(j = 0;j < calcresult.size();++j)
* i' M8 u) A# Q% e9 v7 C9 n- v# W  {  x; T  E. ~7 O" B4 Y! d( `; J
  int bit1 = 0,bit2 = 0,res = 0;% @: R6 j: g! z) ?; B
  bit1 = calcresult[j];9 v0 i! V  a4 o* B0 t! T
  bit2 = tempnum;
  S) E: C+ T2 E1 v3 ~  res = bit1 * bit2;
5 r( C3 L$ ~# C3 M8 a2 ^" g  // 保存当前位! G+ Y8 G$ b- Y8 l
  if((i+j)
* P0 K2 z2 a/ _  {9 u' U% o, O* S0 c- J( o
  // 临时结果中有对应位存在,则直接更新# n; p" f2 s# \1 o* J
  rest[i+j] += (res + carry) % 10;, W4 X; l) K* [6 X8 V$ V
  }
) F$ _5 a" Q  k! ]9 D: \  else' g7 h7 Q6 F; ?
  {! u  e- p( a4 W3 S
  // 没有对应位则需要添加
- }% D9 s- G9 C1 P) K  rest.push_back((res+carry)%10);# G9 R: U) T2 ?. J
  }8 S% x1 J6 G$ g, x, u# A/ {+ g
  // 有进位,则更新进位
+ N) b( C- {/ [  carry = (res + carry) / 10;0 f9 y. {  i+ G  L  y2 A1 D
  }7 e/ i" c5 z2 E) m# F1 ^$ c. W
  // 如果计算之后还有最高位的进位,那么则直接添加进去
# H8 b, i5 |+ c% d/ g/ H1 I* R6 e  if(carry)4 p* l6 K' Y. z: c" M! ~( X
  {  X  O! r8 {/ o$ `+ {7 a* F. r
  // 保存当前位
! B# R  l2 f- V/ Z6 [7 a' _3 q1 Y# u  if((i+j)* t4 O# I* V) t6 J5 m
  {
* N2 ?6 S; C% }& e7 ~5 N$ o3 L; g  // 临时结果中有对应位存在,则直接更新* _% z* }0 R# C/ |9 I7 e( b
  rest[i+j] += carry;. c6 F8 F! U" n. }% I) S
  }# b3 x) A! f6 `! R3 j% e, P- q
  else
# ]) Z$ t3 C' ^) p# ]  {) g7 L* I! ?) W' s& j# m2 d( B# Q
  // 没有对应位则需要添加8 X7 r0 A4 D8 B6 l
  rest.push_back(carry);
& S. z: Q6 v0 L& |" [$ a8 v# M  }/ b- {& G3 f, ^
  }, N9 w+ ^, K. m' U7 F
  }
- X5 J7 n7 ?) V' [* G( P  // 上述计算之后,会出现有些位的数字超过了10,那是因为在处理每一位运算结果之后
' l* W& |% u( m# K( E5 P  // 相加时地位向高位可能存在进位,上面没有考虑,所以需要进行调整& T1 {) ^' S$ R  @# U# V" S, A
  for(i = 0;i < rest.size();++i)
$ U; m4 o2 k  P( R/ W4 e  {
2 H) X* S& X  X* D' ~$ S  if(rest > 9)  s7 W1 {% m+ N# p8 N9 S4 j3 @. w
  {3 w, Q! a0 j3 F
  if((i+1) != rest.size())8 d" s/ `" O) u  j* q: ^% c: |, U" ]
  {
; Z% F9 v, a+ `9 n$ b1 F  // 高位存在,则直接更新高位
. w) I2 L" K% Q, B) u% l$ I  rest[i+1] += rest / 10;$ e3 B6 K6 x5 {2 \) _! c6 [) H4 Q
  rest = rest % 10;
& W' f  H! z2 i, c" D  }
; Q8 r6 u: J4 ~' ]9 s% o9 j! k  else
) a+ G# G. `3 F  {
0 S. d3 E- F: e. j0 a6 y7 B& j# @  // 高位不存在,则需要插入) {( n4 [" o' L7 Z1 P
  rest.push_back(rest / 10);
2 \' ^) K+ i9 S3 n4 L  rest = rest % 10;
) \1 T, M$ j% Y3 k  }: P- T! D; m* V) F
  }
1 u, y1 Q% [( c( }  P4 d/ _8 Q
8 b! R* \" x$ z- @7 N  }
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-7-31 21:57:00 | 显示全部楼层

2012年计算机等级考试二级C++辅导讲义(10)

</p>  // 将计算结果存储到原来的容器中& O! A  ]5 i8 G" ]) g5 f+ ?3 k
  calcresult.clear();
$ |8 i. s  I5 x% d! }4 f  L1 h  for(i = 0;i < rest.size();++i)
' [% X5 v/ k- V! E8 }  {& L  J3 u( a7 g
  calcresult.push_back(rest);
0 w. Q% \1 o: L' x2 {4 |7 n' Y: A* ?2 p5 u  }* o: A9 Z1 q, R- ]
  }
3 u1 D$ j) I" Q2 [3 Y- m" r  int main()
4 f7 t5 p9 f, g8 P# V: r8 L  {" W1 z+ g8 L+ |# N
  int num = 0;
8 T% C: J' _: ?% e* l  vector calcresult;+ S2 h8 c8 n1 a/ |# c4 Y
  // 将初值1赋进去
9 ~- G3 ~4 H( E5 }' l- Y  calcresult.push_back(1);
+ Z7 u2 f: {" ?1 S! Y/ s  // 获取欲求阶乘的整数& P0 _% ]0 y6 O

% m  }" w# V& ~. u6 Y$ j  cout
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-5-4 18:10 , Processed in 0.304435 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表