博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
大数四则运算类
阅读量:4454 次
发布时间:2019-06-07

本文共 10279 字,大约阅读时间需要 34 分钟。

 
#include
"
stdlib.h
"
#include
<
iostream
>
#include
<
assert.h
>
#include
<
time.h
>
#include
<
vector
>
using
namespace
std;
#define
BI_NEG 0
#define
BI_POS 1
class
big_int;
const
big_int
operator
+
(
const
big_int
&
,
const
big_int
&
);
const
big_int
operator
-
(
const
big_int
&
,
const
big_int
&
);
const
big_int
operator
*
(
const
big_int
&
,
const
big_int
&
);
const
big_int
operator
/
(
const
big_int
&
,
const
big_int
&
);
const
big_int
operator
%
(
const
big_int
&
,
const
big_int
&
);
bool
operator
<
(
const
big_int
&
,
const
big_int
&
);
bool
operator
<=
(
const
big_int
&
,
const
big_int
&
);
bool
operator
==
(
const
big_int
&
,
const
big_int
&
);
bool
operator
>=
(
const
big_int
&
,
const
big_int
&
);
bool
operator
>
(
const
big_int
&
,
const
big_int
&
);
ostream
&
operator
<<
(ostream
&
_OStr,
const
big_int
&
rhs);
const
big_int bipow(
const
big_int
&
,
const
int
);
const
big_int bifact(
int
);
class
big_int
{
private
:
static
const
unsigned
base
=
10000
;
int
sign;
vector
<
unsigned
>
number;
public
:
big_int(){number.push_back(
0
);};
big_int(
const
char
*
);
big_int(
const
big_int
&
bi):number(bi.number),sign(bi.sign){};
big_int(
int
);
big_int(
long
long
);
int
get_sign(){
return
sign;};
big_int
&
operator
+=
(
const
big_int
&
);
big_int
&
operator
-=
(
const
big_int
&
);
big_int
&
operator
*=
(
const
big_int
&
);
big_int
&
operator
/=
(
const
big_int
&
);
big_int
&
operator
%=
(
const
big_int
&
);
void
output();
private
:
friend
bool
operator
<
(
const
big_int
&
,
const
big_int
&
);
friend ostream
&
operator
<<
(ostream
&
,
const
big_int
&
);
//
number加上rhs的number
void
add(
const
vector
<
unsigned
>
&
);
//
两个相减,结果放回number中
void
minus(
const
vector
<
unsigned
>
&
,
const
vector
<
unsigned
>
&
);
void
minus(
const
vector
<
unsigned
>
&
);
static
bool
less(
const
vector
<
unsigned
>
&
,
const
vector
<
unsigned
>
&
);
};
big_int::big_int(
int
n)
{
if
(n
<
0
) sign
=
BI_NEG;
else
sign
=
BI_POS;
if
(n
==
0
) {number.push_back(
0
);}
else
{
if
(n
<
0
) n
=
-
n;
while
(n
!=
0
)
{
number.push_back(n
%
base
);
n
/=
base
;
}
}
}
big_int::big_int(
long
long
n)
{
if
(n
<
0
) sign
=
BI_NEG;
else
sign
=
BI_POS;
if
(n
==
0
) {number.push_back(
0
);}
else
{
if
(n
<
0
) n
=
-
n;
while
(n
!=
0
)
{
number.push_back((
int
)(n
%
base
));
n
/=
base
;
}
}
}
big_int::big_int(
const
char
*
str)
{
int
len
=
strlen(str);
assert(len
>
0
);
int
from
=
0
;
int
temp
=
0
;
if
(str[
0
]
==
'
-
'
){sign
=
BI_NEG; from
=
1
;}
else
{sign
=
BI_POS;}
int
idx
=
len
-
1
;
int
de
=
0
;
int
times
=
1
;
while
(idx
-
de
>=
from)
{
if
(de
%
4
==
0
)
{
times
=
1
;
}
temp
+=
(times
*
(str[idx
-
de]
-
'
0
'
));
times
*=
10
;
if
(de
%
4
==
3
)
{
number.push_back(temp);
temp
=
0
;
}
++
de;
}
if
(temp
!=
0
) number.push_back(temp);
int
i
=
number.size()
-
1
;
while
(i
>
0
&&
number[i]
==
0
){number.pop_back();
--
i;}
if
(number.size()
==
0
) {number.push_back(
0
);sign
=
BI_POS;}
}
void
big_int::output()
{
if
(sign
==
BI_NEG) cout
<<
'
-
'
;
cout
<<
number[number.size()
-
1
];
for
(
int
i
=
number.size()
-
2
; i
>=
0
;
--
i)
{
cout
<<
number[i]
/
1000
<<
(number[i]
%
1000
)
/
100
<<
(number[i]
%
100
)
/
10
<<
number[i]
%
10
;
}
}
bool
big_int::less(
const
vector
<
unsigned
>
&
lhs,
const
vector
<
unsigned
>
&
rhs)
{
if
(lhs.size()
<
rhs.size())
return
true
;
else
if
(rhs.size()
<
lhs.size())
return
false
;
else
{
for
(
int
i
=
lhs.size()
-
1
; i
>=
0
;
--
i)
{
if
(lhs[i]
<
rhs[i])
return
true
;
else
if
(rhs[i]
<
lhs[i])
return
false
;
}
}
return
false
;
}
void
big_int::add(
const
vector
<
unsigned
>
&
rhs)
{
int
nleft
=
number.size();
int
nright
=
rhs.size();
int
i
=
0
;
unsigned c
=
0
;
unsigned temp
=
0
;
while
(nleft
<
nright){ number.push_back(
0
);
++
nleft;}
while
(i
<
nright)
{
temp
=
number[i]
+
rhs[i]
+
c;
number[i]
=
temp
%
base
;
c
=
temp
/
base
;
++
i;
}
while
(i
<
nleft
&&
c
!=
0
)
{
temp
=
number[i]
+
c;
number[i]
=
temp
%
base
;
c
=
temp
/
base
;
++
i;
}
if
(c
!=
0
) number.push_back(c);
}
void
big_int::minus(
const
vector
<
unsigned
>
&
lhs,
const
vector
<
unsigned
>
&
rhs)
{
vector
<
unsigned
>
res;
int
nleft
=
lhs.size();
int
nright
=
rhs.size();
int
i
=
0
;
unsigned c
=
0
;
unsigned temp
=
0
;
res.resize(nleft);
for
(i
=
nleft
-
1
; i
>=
0
;
--
i) res[i]
=
0
;
i
=
0
;
while
(i
<
nright)
{
temp
=
lhs[i]
+
base
-
rhs[i]
-
c;
res[i]
=
temp
%
base
;
c
=
temp
/
base
;
c
=
(c
==
1
?
0
:
1
);
++
i;
}
while
(i
<
nleft)
{
temp
=
lhs[i]
+
base
-
c;
res[i]
=
temp
%
base
;
c
=
temp
/
base
;
c
=
(c
==
1
?
0
:
1
);
++
i;
}
i
=
nleft
-
1
;
while
(i
>
0
&&
res[i]
==
0
){ res.pop_back();
--
i;}
number
=
res;
}
void
big_int::minus(
const
vector
<
unsigned
>
&
rhs)
{
int
nleft
=
number.size();
int
nright
=
rhs.size();
int
i
=
0
;
unsigned c
=
0
;
unsigned temp
=
0
;
while
(i
<
nright)
{
temp
=
number[i]
+
base
-
rhs[i]
-
c;
number[i]
=
temp
%
base
;
c
=
temp
/
base
;
c
=
(c
==
1
?
0
:
1
);
++
i;
}
while
(i
<
nleft)
{
temp
=
number[i]
+
base
-
c;
number[i]
=
temp
%
base
;
c
=
temp
/
base
;
c
=
(c
==
1
?
0
:
1
);
++
i;
}
i
=
nleft
-
1
;
while
(i
>
0
&&
number[i]
==
0
){number.pop_back();
--
i;}
}
big_int
&
big_int::
operator
+=
(
const
big_int
&
rhs)
{
if
(rhs.sign
==
sign){ add(rhs.number);}
//
同号相加
else
if
(less(number, rhs.number))
//
绝对值较小
{
sign
=
rhs.sign;
minus(rhs.number,number);
}
else
{
minus(rhs.number);
}
return
*
this
;
}
big_int
&
big_int::
operator
-=
(
const
big_int
&
rhs)
{
if
(rhs.sign
!=
sign){ add(rhs.number);}
//
异号则相加
else
if
(less(number, rhs.number))
{
sign
=
sign
^
1
;
minus(rhs.number, number);
}
else
{
minus(rhs.number);
}
return
*
this
;
}
big_int
&
big_int::
operator
*=
(
const
big_int
&
rhs)
{
if
(sign
!=
rhs.sign) sign
=
BI_NEG;
else
sign
=
BI_POS;
int
nleft
=
number.size();
int
nright
=
rhs.number.size();
int
i,j,c,temp,idx;
int
maxlen
=
nleft
+
nright
+
1
;
vector
<
unsigned
>
res;
res.resize(maxlen);
for
(i
=
0
; i
<
maxlen;
++
i){ res[i]
=
0
;};
for
(i
=
0
; i
<
nright;
++
i)
{
c
=
0
; temp
=
0
; idx
=
i;
for
(j
=
0
; j
<
nleft;
++
j)
{
temp
=
number[j]
*
rhs.number[i]
+
res[idx]
+
c;
res[idx]
=
temp
%
base
;
c
=
temp
/
base
;
++
idx;
}
while
(c
!=
0
)
{
temp
=
res[idx]
+
c;
res[idx]
=
temp
%
base
;
c
=
temp
/
base
;
++
idx;
}
}
i
=
res.size()
-
1
;
while
(i
>
0
&&
res[i]
==
0
){res.pop_back();
--
i;}
number
=
res;
return
*
this
;
}
big_int
&
big_int::
operator
/=
(
const
big_int
&
rhs)
{
int
nleft
=
number.size();
int
nright
=
rhs.number.size();
int
i, temp;
if
(sign
!=
rhs.sign) sign
=
BI_NEG;
else
sign
=
BI_POS;
assert(
!
(nright
==
1
&&
rhs.number[
0
]
==
0
));
//
除数不为0
if
(less(number,rhs.number))
{
number.resize(
0
); number.push_back(
0
);sign
=
BI_POS;
return
*
this
;
}
vector
<
unsigned
>
diver;
vector
<
unsigned
>
mid;
vector
<
unsigned
>
res;
diver.resize(nright
+
1
);
mid.resize(nright
+
1
);
for
(i
=
0
; i
<=
nright;
++
i) diver[i]
=
0
;
res.resize(nleft
-
nright
+
1
);
for
(i
=
0
; i
<=
nleft
-
nright;
++
i) res[i]
=
0
;
int
ires
=
nleft
-
nright;
int
idx
=
nleft
-
nright
+
1
;
for
(i
=
0
; i
<
nright
-
1
;
++
i)
{
diver[i]
=
number[idx
+
i];
}
--
idx;
int
max_idx_diver
=
diver.size()
-
1
;
int
max_idx_right
=
rhs.number.size()
-
1
;
int
temp_res;
int
c, temp2;
for
(; idx
>=
0
;
--
idx)
{
for
(i
=
max_idx_diver; i
>
0
;
--
i) diver[i]
=
diver[i
-
1
];
diver[
0
]
=
number[idx];
temp
=
diver[max_idx_diver]
*
base
+
diver[max_idx_diver
-
1
];
temp_res
=
temp
/
rhs.number[max_idx_right];
while
(temp_res
>=
0
)
{
c
=
0
;
for
(i
=
0
; i
<=
max_idx_right;
++
i)
{
temp2
=
rhs.number[i]
*
temp_res
+
c;
mid[i]
=
temp2
%
base
;
c
=
temp2
/
base
;
}
mid[max_idx_diver]
=
c;
if
(less(diver,mid))
--
temp_res;
else
break
;
}
c
=
0
;
for
(i
=
0
; i
<=
max_idx_right;
++
i)
{
temp2
=
rhs.number[i]
*
temp_res
+
c;
mid[i]
=
temp2
%
base
;
c
=
temp2
/
base
;
}
mid[max_idx_diver]
=
c;
c
=
0
;
for
(i
=
0
; i
<=
max_idx_diver;
++
i)
{
temp2
=
diver[i]
+
base
-
mid[i]
-
c;
diver[i]
=
temp2
%
base
;
c
=
temp2
/
base
;
c
=
c
^
1
;
}
res[idx]
=
temp_res;
}
i
=
res.size()
-
1
;
while
(i
>
0
&&
res[i]
==
0
){res.pop_back();
--
i;}
number
=
res;
return
*
this
;
}
big_int
&
big_int::
operator
%=
(
const
big_int
&
rhs)
{
int
nleft
=
number.size();
int
nright
=
number.size();
assert(
!
(nright
==
1
&&
rhs.number[
0
]
==
0
));
//
符号不变
if
(less(number,rhs.number))
return
*
this
;
big_int bi1(
*
this
);
bi1
/=
rhs;
bi1
*=
rhs;
big_int bi2(
*
this
);
bi2
-=
bi1;
number
=
bi2.number;
if
(number.size()
==
1
&&
number[
0
]
==
0
) sign
=
BI_POS;
return
*
this
;
}
//
const
big_int
operator
+
(
const
big_int
&
lhs,
const
big_int
&
rhs)
{
big_int res(lhs);
res
+=
rhs;
return
res;
}
const
big_int
operator
-
(
const
big_int
&
lhs,
const
big_int
&
rhs)
{
big_int res(lhs);
res
-=
rhs;
return
res;
}
const
big_int
operator
*
(
const
big_int
&
lhs,
const
big_int
&
rhs)
{
big_int res(lhs);
res
*=
rhs;
return
res;
}
const
big_int
operator
/
(
const
big_int
&
lhs,
const
big_int
&
rhs)
{
big_int res(lhs);
res
/=
rhs;
return
res;
}
const
big_int
operator
%
(
const
big_int
&
lhs,
const
big_int
&
rhs)
{
big_int res(lhs);
res
%=
rhs;
return
res;
}
bool
operator
<
(
const
big_int
&
lhs,
const
big_int
&
rhs)
{
if
(lhs.sign
<
rhs.sign)
return
true
;
else
if
(rhs.sign
<
lhs.sign)
return
false
;
else
if
(lhs.sign
==
BI_POS)
return
big_int::less(lhs.number,rhs.number);
else
return
big_int::less(rhs.number, lhs.number);
}
bool
operator
<=
(
const
big_int
&
lhs,
const
big_int
&
rhs)
{
return
!
(rhs
<
lhs);
}
bool
operator
==
(
const
big_int
&
lhs,
const
big_int
&
rhs)
{
return
!
(rhs
<
lhs)
&&
!
(lhs
<
rhs);
}
bool
operator
>=
(
const
big_int
&
lhs,
const
big_int
&
rhs)
{
return
!
(lhs
<
rhs);
}
bool
operator
>
(
const
big_int
&
lhs,
const
big_int
&
rhs)
{
return
rhs
<
lhs;
}
ostream
&
operator
<<
(ostream
&
_OStr,
const
big_int
&
rhs)
{
if
(rhs.sign
==
BI_NEG) _OStr
<<
'
-
'
;
_OStr
<<
rhs.number[rhs.number.size()
-
1
];
for
(
int
i
=
rhs.number.size()
-
2
; i
>=
0
;
--
i)
{
_OStr
<<
rhs.number[i]
/
1000
<<
(rhs.number[i]
%
1000
)
/
100
<<
(rhs.number[i]
%
100
)
/
10
<<
rhs.number[i]
%
10
;
}
return
_OStr;
}
const
big_int bipow(
const
big_int
&
lhs,
const
int
rhs)
{
assert(rhs
>=
0
);
big_int res(
1
);
for
(
int
i
=
0
; i
<
rhs;
++
i)
{
res
*=
lhs;
}
return
res;
}
const
big_int bifact(
int
n)
{
big_int res(
1
);
for
(
int
i
=
2
; i
<=
n;
++
i)
{
res
*=
i;
}
return
res;
}

 

转载于:https://www.cnblogs.com/one-piece/archive/2010/05/31/1748385.html

你可能感兴趣的文章
CString与char* 相互转换
查看>>
数据区的内存模型
查看>>
E20190404-hm
查看>>
IIS负载均衡的NLB解决方案
查看>>
windows 游戏编程大师 读书笔记
查看>>
avalon.js中使用owl-carousel轮播图
查看>>
phpcms笔记
查看>>
今天第一天,思考
查看>>
图层时间之层级关系时间
查看>>
常见算法之0---冒泡排序
查看>>
Spring boot 默认首页配置
查看>>
host的作用
查看>>
为什么operator<<运算符重载一定要为友元函数
查看>>
jsonp跨域
查看>>
再温习JAVA命名规范
查看>>
libevent学习过程
查看>>
webview加载页面为什么在UI线程里面做,难道不是耗时操作么
查看>>
TensorFlow 安装 Ubuntu14.04
查看>>
springmvc 注解 RequestParam/RequestHeader/CookieValue
查看>>
20175310 《Java程序设计》第1周学习总结(1)安装虚拟机
查看>>