|
高精度,用一个线性表保存一个大整数,具体说,将大整数写成p进制数,线性表的每一项存p进制其中一位。 参考下面代码 #include <iostream>
$ L" c% o9 h# r" d#include <memory>! o, q& `/ ~, ~9 {
# include <string>9 T, D( T3 |& o$ n
using namespace std; typedef long long hugeint; const int Base = 1000000000;
& `+ |0 x t6 hconst int Capacity = 200; struct xnum/ d' A$ G; }7 d8 B: `8 t8 e
{
v. N8 Q$ A$ M: N; S, i1 d) g int Len;
9 H, p, ?0 G4 O$ R1 e int Data[Capacity];: b: ]) N; T; f4 Q( y: E0 L7 E
xnum() : Len(0) {}
$ i9 o% h- l" l xnum(const xnum& V) : Len(V.Len) { memcpy(Data, V.Data, Len * sizeof *Data); }
4 K: m- J4 `# E9 X [1 u6 d: l. H xnum(int V) : Len(0) { for (; V > 0; V /= Base) Data[Len++] = V % Base; }
% r. R8 t1 ?- V+ F xnum& operator=(const xnum& V) { Len = V.Len; memcpy(Data, V.Data, Len * sizeof *Data); return *this; }
8 \/ d1 b! l; \7 k( r- _5 q1 i int& operator[](int Index) { return Data[Index]; }0 M8 ]4 l' O- O+ I5 B' G
int operator[](int Index) const { return Data[Index]; }9 C" l1 U! Y/ `- A! K
};
, q u& C* U9 lint compare(const xnum& A, const xnum& B)& Q: ~6 i$ X2 t7 ^* U3 Q6 {* M
{: e- T/ z& s: H0 }
int I;/ B9 J% d7 t$ q! n! l/ K
if (A.Len != B.Len) return A.Len > B.Len ? 1 : -1;7 r% ]) ]5 q2 e/ \6 r* S; `
for (I = A.Len - 1; I >= 0 && A[I] == B[I]; I--);* P& D& n1 E# p% E3 |2 @1 P
if (I < 0) return 0;
6 z: x4 S0 I8 ]7 U) A) F5 p. { return A[I] > B[I] ? 1 : -1;8 u" U/ f; j- C( C* a2 k
} xnum operator+(const xnum& A, const xnum& B)
: f8 i$ n1 B: a$ w: v R{) v& Q0 H. k6 `6 ?. p! I: a" W
xnum R;$ s7 j! @ A- J6 D
int I;
8 F5 e M$ E- O9 N1 a int Carry = 0;4 e" `* m# Z( t4 j/ K- C. K$ T$ { P
for (I = 0; I < A.Len || I < B.Len || Carry > 0; I++): ]: N' H; o6 l! k: c% z) {+ c
{+ ?0 C6 J' M) @( `& @6 j
if (I < A.Len) Carry += A[I];1 j$ N# O v0 Y6 Z. H) M
if (I < B.Len) Carry += B[I];2 n9 R3 i! M, r, U
R[I] = Carry % Base;
+ J- w- A4 s9 s+ [* J- G Carry /= Base;
% P8 e2 d( A' i4 A5 _ }6 |0 B# [' H0 N ^1 A. j) }& \
R.Len = I;# N8 `, O0 [3 t4 U* z% g( d
return R;, i ?, {) f) B
} xnum operator-(const xnum& A, const xnum& B)) ^+ }- x, U/ y j% G$ r/ t2 B
{
# F! D" V. J) I5 O2 | xnum R;* ]9 F# B& S5 J- ?
int Carry = 0;; R J* c9 A+ \- m0 v
R.Len = A.Len;
# L3 o* r- Q9 X- v4 A9 V2 Y int I;+ R- ?2 z1 S* h: _- J8 ~
for (I = 0; I < R.Len; I++)
7 e$ i$ y) _: @$ C {
$ D9 Y* y) p9 \5 u |' M8 D# o R[I] = A[I] - Carry;
. k# D+ }. G; A6 H: W# F% A. n# a if (I < B.Len) R[I] -= B[I];0 R+ u* c6 e' s# G% K
if (R[I] < 0) Carry = 1, R[I] += Base;
. e) {9 x' N0 V else Carry = 0;# j# r3 ^, G" f/ G; R6 ^" J/ u6 t
}* I2 r- V( w! I) o1 ~- I
while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;$ d7 z2 u9 W* \* T
return R;1 {1 }* G+ x' K; y; B' | N: `
} xnum operator*(const xnum& A, const int B)7 l; K w( S/ r$ o
{
1 v3 T% b; q5 r6 { int I;
6 d) D8 Y3 F; l9 v2 g if (B == 0) return 0;' K0 j* |: F/ O1 j' X$ B
xnum R;
7 b9 O% D6 P9 c: n hugeint Carry = 0;' y) S) Q. Z* m. C! @ q" M
for (I = 0; I < A.Len || Carry > 0; I++)
9 @) F; |/ Q/ j5 N* x" p1 p2 e/ H {
) X+ d; K+ Q/ b' k$ s5 Y ] if (I < A.Len) Carry += hugeint(A[I]) * B;0 Z% H8 X' I$ G6 o% u8 [
R[I] = Carry % Base;
( M g/ p' ^2 Q8 C$ I Carry /= Base;$ x$ Z8 F$ L" d; H8 M2 c! l8 h) A
}7 T+ k: V6 Z9 r# G
R.Len = I;. i) f1 n5 H; y3 ^! _
return R;, c% w8 X1 k) K3 D2 [: Y
} xnum operator*(const xnum& A, const xnum& B)/ M: Y/ k9 S. w) i
{
7 S: F/ c+ [1 C# | k( O int I; S7 M9 U# J+ D( v: s [, @1 t
if (B.Len == 0) return 0;
" d( a% b8 Y( H) Z0 Y' W7 z xnum R;
/ g5 z. f e3 B0 a8 r- V for (I = 0; I < A.Len; I++)
: p4 N3 U. l4 @8 h" O {0 `: b; ?( u5 z
hugeint Carry = 0;5 b" x4 ^4 u2 c$ s8 t6 c
for (int J = 0; J < B.Len || Carry > 0; J++)
* [ Q1 r& X* E$ X {% D' e1 q' w) B+ y) _" g7 o
if (J < B.Len) Carry += hugeint(A[I]) * B[J];5 Q- g; H9 A; k4 L* j
if (I + J < R.Len) Carry += R[I + J];
! H6 I2 s+ h0 D. \ if (I + J >= R.Len) R[R.Len++] = Carry % Base;3 Q3 P8 X- @! |) g, P1 L1 w
else R[I + J] = Carry % Base;" m7 O$ P# y0 H% j2 t
Carry /= Base;
, `" b7 | o2 S0 ?8 U } ' n; `0 W4 \2 [* |% R. O, S0 ~
}7 n* Z- M0 J, |/ x1 w
return R;
; ^. J. D. g7 ~, G3 O7 C3 v" M: z! r" J} xnum operator/(const xnum& A, const int B)
( I3 R+ |! d, {/ B# B{+ @/ k# t& o5 l2 p1 x
xnum R;
# u: H- o& q% N x# {" `0 |0 o int I;/ C4 ^- B; w/ z
hugeint C = 0;1 k6 U8 k. [9 c# w
for (I = A.Len - 1; I >= 0; I--)
3 L# G& U7 q) x8 t L {1 Y5 s1 T' Z0 f, y; O
C = C * Base + A[I];2 u6 V$ t0 a+ @. u% [- |
R[I] = C / B;
& ~# ~$ b. y4 f/ y" ]2 l C %= B;4 \" a9 t1 |( P6 q- S) A
} j4 l3 e! i3 m9 ]/ Q5 h9 u; T, j
R.Len = A.Len;9 n$ k* G9 ?. N* Y! M
while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;
9 `. R x n9 ^3 W9 j return R;; S7 |6 H/ Y* G, z
} xnum operator/(const xnum& A, const xnum& B)- c' `; L1 L; C& _/ [; }# S5 Y! b
{
* m) ` l- p m1 }8 J int I;, { m; s7 i* k# n; h
xnum R, Carry = 0; l$ T: X. V8 N; M4 G8 E, l; j
int Left, Right, Mid;
0 u$ t% [: g4 T( ^0 a0 P- z# w* ] for (I = A.Len - 1; I >= 0; I--)$ h' r7 [/ ^/ X* }1 x/ d9 m0 w* x
{6 r( |+ x& ^$ T
Carry = Carry * Base + A[I];: |: @! o9 Q' o( V- H/ l" ^/ |
Left = 0;
9 v. l! ?3 ~' `7 U) ?/ I6 U, { Right = Base - 1;& M8 I5 u" c, ^2 S2 F; J
while (Left < Right)
# X1 s9 j3 S; p5 \4 b {
* P% C$ a& ~) s Mid = (Left + Right + 1) / 2;, }& U$ F: |" k: L
if (compare(B * Mid, Carry) <= 0) Left = Mid;: w3 h; M% E" `& \$ S0 o' @7 L( Z
else Right = Mid - 1;
) F4 w) l* I: g$ O }
A. X2 t# K1 ? I) o R[I] = Left;
" _2 ]- X( ^, S7 i. @; S Carry = Carry - B * Left;
1 j5 z& b1 Y: z2 J }
0 D4 G6 i# C; ~1 d" _9 d2 A2 g( J R.Len = A.Len;& t$ L1 G$ [0 ^6 g7 S/ {9 f$ _
while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;
- S$ Q s) ?, j1 |5 H5 B s return R;
2 |" e, k* J( `$ `- F) N* }3 z}
- }0 _- Q) j6 Z, Z. uxnum operator%(const xnum& A, const xnum& B)) P0 v3 p- N) `( P0 E" T
{
$ B6 g$ @9 |4 `; ^ int I;
" I3 `9 w/ A+ U xnum R, Carry = 0;2 r' P( ~' H/ O* o7 M; [
int Left, Right, Mid;
P! u6 }& g* h9 ~5 G for (I = A.Len - 1; I >= 0; I--)
* G" C+ u+ A; l% | {0 t- k$ D3 |+ v; g1 m0 d- h( D
Carry = Carry * Base + A[I];) J$ @# ]7 y) ~ R$ ]" L
Left = 0;+ u8 b# V, I O. e7 H3 a
Right = Base - 1;! E3 g- ]8 ^/ G9 K& Z8 H5 } A
while (Left < Right)0 `0 `6 _4 o2 q! j& {* `
{8 K, n" q+ w" M
Mid = (Left + Right + 1) / 2; Z3 B; D+ J% K: A- A$ n f) t6 M
if (compare(B * Mid, Carry) <= 0) Left = Mid;% ?# t9 o! p+ Q! v" a
else Right = Mid - 1;" ]9 T* j. u7 m& w* _, z1 v
}
0 Z( Z# w+ S- P4 M8 m R[I] = Left;( P7 J P7 x c1 f( g p
Carry = Carry - B * Left;
d% t, I/ c3 k6 {5 M1 v }8 k( r: n: G, u G& T: N
R.Len = A.Len;
4 B# ~6 Y; a) z7 e' D. f while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;1 m$ \& r% i3 ]. O0 ?
return Carry;
- ]1 T7 c% Q- E, T% D! U} istream& operator>>(istream& In, xnum& V)
2 `" K, R! c2 H$ k& L{# I8 h" F7 k) K8 q/ N( P9 C
char Ch;
* v; V8 t' `" p9 A2 r9 r7 I for (V = 0; In >> Ch;)4 n8 ~) u; Z0 q6 s. U
{
8 l8 t* v# c5 g V = V * 10 + (Ch - '0');
/ ~" Z3 B+ u ? if (cin.peek() <= ' ') break;% ^" a; ]* M- H/ }
}
, B) N4 R0 j4 _+ g6 j& Q return In;
2 y* G$ B% U5 w9 m- ?% o0 d+ }} ostream& operator<<(ostream& Out, const xnum& V)% C! O( E* r, h& j0 z/ L. P% M
{
6 v# o4 T T1 g) H" m+ n int I;6 T0 g5 L5 z7 Y$ ~, Y" h4 }- d
Out << (V.Len == 0 ? 0 : V[V.Len - 1]);, M8 \" y' ^- D( W) N0 ~
for (I = V.Len - 2; I >= 0; I--) for (int J = Base / 10; J > 0; J /= 10) Out << V[I] / J % 10;
1 P ~. v8 d2 e( D/ c' Z/ ]+ G return Out;) s# u" L; G- v% K$ V
}
( d9 ^+ t" [/ B8 u, B2 G+ | |