大数幂运算 源于POJ1001题目:http://acm.pku.edu.cn/JudgeOnline/problem?id=1001
这个题目可以从简单问题一步一步入手。
1. 先仿效上一篇计算大整数加法,计算一个大整数与一个个位数字的乘积 string Mul_singleInt(const string& s1, int n);
2. 循环利用大整数加法计算大整数乘积 string Mul_int(const string& s1, const string& s2);
3. 循环利用大整数乘积得到大数幂string Exponentiation(const string& s1, int exp); 其中如果底数是浮点数,先去掉小数点,最后补上。
举例: 2.0100^3
计算2.0100×2.0100×2.0100
2.0100×2.0100 = 2.01×2.01 = 201×201×10^(-4)
201*201 = 201*1 + 201*0*10 + 201*1*(10^2)
代码实现:
#include <string>
#include <iostream>
#include <algorithm>
using
std
::
string;
using
std
::
cout;
using
std
::
cin;
using
std
::
max;
using
std
::
endl;
using
std
::
getline;
string
Add(
const
string
&
s1
,
const
string
&
s2);
string
Mul_singleInt(
const
string
&
s1
,
int n);
string
Mul_int(
const
string
&
s1
,
const
string
&
s2);
int
CalPointNum(
const
string
&
s1
,
const
string
&
s2);
void
RemoveZero(
string
& s);
void
RemoveDot(
string
& s);
string
Exponentiation(
const
string
&
s1
,
int
exp);
string
Mul_singleInt(
const
string
&
s1
,
int n)
{
string
ret;
int
len1
=
s1
.
length();
if (
len1
<=
0)
return
ret;
int
*
num1
=
new
int
[
len1
+
1
];
for (
int
i
=
0;
i
<=
len1;
++
i)
{
num1
[
i
]
=
0;
}
for (
int
j
=
0
,
i
=
len1
-
1;
i
>=
0;
++
j
,
--
i)
{
num1
[
j
]
=
s1
[
i
]
-
'0';
}
// multiply every int element in array
int
lastCarry
=
0;
for (
int
i
=
0;
i
<
len1;
++
i)
{
num1
[
i
]
*= n;
num1
[
i
]
+=
lastCarry;
lastCarry
=
num1
[
i
]
/
10;
num1
[
i
]
-=
lastCarry
*
10;
}
num1
[
len1
]
+=
lastCarry;
//store result.
int
i
=
len1;
while(
num1
[
i
]
==
0)
--
i;
for (
i;
i
>=
0;
--
i)
{
ret
.
push_back(
'0'
+
num1
[
i
]);
}
delete
[]
num1;
return
ret;
}
string
Mul_int(
const
string
&
s1
,
const
string
&
s2)
{
int
len1
=
s1
.
length();
int
len2
=
s2
.
length();
int
len
=
len1
+
len2;
int
*
num1
=
new
int
[
len
];
int
*
num2
=
new
int
[
len
];
string
ret1;
string
ret;
int n;
for (
int
i
=
len2
-
1;
i
>=
0;
i
--)
{
n
=
s2
[
i
]
-
'0';
//n = atoi(s2[i]);
ret1
=
Mul_singleInt(
s1
, n);
for (
int
j
=
len2
-
i
-
1;
j
>
0;
j
--)
ret1
.
push_back(
'0');
ret
=
Add(
ret
,
ret1);
}
return
ret;
}
string
Mul_float(
const
string
&
s1
,
const
string
&
s2)
{
int
ndot
=
CalPointNum(
s1
,
s2);
string
ss1(
s1);
string
ss2(
s2);
int
pos1
=
ss1
.
find(
'.');
int
pos2
=
ss2
.
find(
'.');
if (
pos1
>=
0)
{
// need to erase '.'
RemoveZero(
ss1);
RemoveDot(
ss1);
}
if (
pos2
>=
0)
{
// need to erase '.'
RemoveZero(
ss2);
RemoveDot(
ss2);
}
string
ret;
ret
=
Mul_int(
ss1
,
ss2);
for (
int
j
=
ndot
-
ret
.
length();
j
>
0;
j
--)
ret
.
insert(
ret
.
begin
(),
'0');
if (
ndot
>
0)
{
string
::
iterator
dotitr
=
ret
.
end()
-
ndot;
ret
.
insert(
dotitr
,
'.');
}
return
ret;
}
string
Add(
const
string
&
s1
,
const
string
&
s2)
{
//int num1[] <- s1;
//int num2[] <- s2;
int
len
=
max(
s1
.
length
(),
s2
.
length());
int
*
num1
=
new
int
[
len
+
1
];
int
*
num2
=
new
int
[
len
+
1
];
for (
int
i
=
0;
i
<=
len;
++
i)
{
num1
[
i
]
=
0;
num2
[
i
]
=
0;
}
int
len1
,
len2;
len1
=
s1
.
length();
len2
=
s2
.
length();
for (
int
i
=
len1
-
1
,
j
=
0;
i
>=
0;
--
i
,
++
j)
{
num1
[
j
]
=
s1
[
i
]
-
'0';
}
for (
int
i
=
len2
-
1
,
j
=
0;
i
>=
0;
--
i
,
++
j)
{
num2
[
j
]
=
s2
[
i
]
-
'0';
}
//add every int element in array
for (
int
i
=
0;
i
<
len;
++
i)
{
num1
[
i
]
+=
num2
[
i
];
if (
num1
[
i
]
>=
10)
{
num1
[
i
]
-=
10;
num1
[
i
+
1
]
++;
}
}
//store result.
string
ret;
int
i
=
len;
while(
num1
[
i
]
==
0)
--
i;
for (
i;
i
>=
0;
--
i)
{
ret
.
push_back(
'0'
+
num1
[
i
]);
}
delete
[]
num1;
delete
[]
num2;
return
ret;
}
void
RemoveZero(
string
& s)
{
while (s
[
0
]
==
'0')
{
string
::
iterator
itr
= s
.
begin();
s
.
erase(
itr);
}
while (
*(s
.
end()
-
1)
==
'0')
{
string
::
iterator
itr
= s
.
end()
-
1;
s
.
erase(
itr);
}
return;
}
void
RemoveDot(
string
& s)
{
int
pos
= s
.
find(
'.');
if (
pos
>=
0)
{
string
::
iterator
itr
= s
.
begin()
+
pos;
s
.
erase(
itr);
}
}
int
CalPointNum(
const
string
&
s1
,
const
string
&
s2)
{
if (
s1
.
find(
'.')
>=
0)
{
}
int
pos1
=
s1
.
find(
'.');
if (
pos1
>=
0)
{
string s(
s1);
while (
*(s
.
end()
-
1)
==
'0')
{
string
::
iterator
itr
= s
.
end()
-
1;
s
.
erase(
itr);
}
pos1
= s
.
length()
-
pos1
-
1;
}
else
pos1
=
0;
int
pos2
=
s2
.
find(
'.');
if (
pos2
>=
0)
{
string s(
s2);
while (
*(s
.
end()
-
1)
==
'0')
{
string
::
iterator
itr
= s
.
end()
-
1;
s
.
erase(
itr);
}
pos2
= s
.
length()
-
pos2
-
1;
}
else
pos2
=
0;
return
pos1
+
pos2;
}
string
Exponentiation(
const
string
&
s1
,
int
exp)
{
string
ret(
"1");
for (
int
i
=
0;
i
<
exp;
i
++)
{
ret
=
Mul_float(
ret
,
s1);
}
return
ret;
}
int
main()
{
string
str1
, s;
int
exp;
while (
cin
>>
str1
>>
exp)
{
string
ret;
ret
=
Exponentiation(
str1
,
exp);
cout
<<
ret
<<
endl;
}
return
0;
}