您的位置:首页 > 其它

UVA 10106 Product 简单高精度乘法

2014-07-04 16:04 423 查看
题目要求输入两个非负的整数后求出他们的积

两个数的范围可以超出 long long型

第一次做高精度的题,这是我自己写的AC代码:

用字符串模拟乘法运算:

Result  :  Accepted     Memory  :  0 KB     Time :  16 ms

/*
* Author: Gatevin
* Created Time:  2014/7/3 16:12:18
* File Name: test.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;

string s1,s2;

int main()
{
while(cin>>s1>>s2)
{
if(s1.length() == 1 && s1[0] == '0')//处理输入有零的情况
{
cout<<"0"<<endl;
continue;
}
if(s2.length() == 1 && s2[0] == '0')
{
cout<<"0"<<endl;
continue;
}
reverse(s1.begin(), s1.end());//先将数字从末尾到首位摆放
reverse(s2.begin(), s2.end());
string ans(s1.length() + s2.length() + 1, '0');//两个整数相乘,积的位数不会超过他们的位数和
int c = 0;
for(int i = 0; i < s1.length(); i++)//模拟乘法运算
{
c = 0;
for(int j = 0; j < s2.length(); j++)
{
/*
*一个数的倒数第i位乘上另一个数的倒数第j位改变的是倒数第i + j位(i,j是编号,从0开始)
*/
int tmp1 =  ((ans[i + j] - '0') + (s1[i] - '0')*(s2[j] - '0') + c) / 10;
int tmp2 =  ((ans[i + j] - '0') + (s1[i] - '0')*(s2[j] - '0') + c) % 10;
ans[i + j] = tmp2 + '0';
c = tmp1;
}
ans[i + s2.length()] += c;
}
int flag;
for(int i = ans.length() - 1; i >= 0; i--)//输出忽略前导零
{
if(ans[i] != '0')
{
flag = i;
break;
}
}
for(int i = flag; i >= 0; i--)
{
cout<<ans[i];
}
cout<<endl;
}
return 0;
}


这是之后使用高精度运算模板的代码:

Result  :  Accepted   Memory  : 0 KB   Time  :  13 ms

/*
* Author: Gatevin
* Created Time:  2014/7/4 12:58:26
* File Name: test.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;

struct bign
{
int len,s[1000];
bign()
{
len = 0;
memset(s, 0 ,sizeof(s));
}

bign operator = (const char* num)
{
len = strlen(num);
for(int i = 0; i < len; i++)
{
s[i] = num[len - i - 1] - '0';
}
return *this;
}

bign operator = (int num)
{
char s[1000];
sprintf(s, "%d", num);
*this = s;
return *this;
}

bign(int num)
{
*this = num;
}

bign(const char* num)
{
*this = num;
}

string str() const
{
string res = "";
for(int i = 0; i < len; i++)
{
res = (char)(s[i] + '0') + res;
}
if(res == "")
{
res = "0";
}
return res;
}

bign operator + (const bign& b) const
{
bign c;
c.len = 0;
for(int i = 0, g = 0; g || i < max(len, b.len); i++)
{
int x = g;
if(i < len) x += s[i];
if(i < b.len) x += b.s[i];
c.s[c.len++] = x % 10;
g = x / 10;
}
return c;
}

bign operator * (const bign& b) const
{
bign c;
c.len = len + b.len;
int k;
for(int i = 0; i < len; i++)
{
k = 0;
for(int j = 0; j < b.len; j++)
{
int tmp1 = (s[i] * b.s[j] + k + c.s[i + j]) / 10;
int tmp2 = (s[i] * b.s[j] + k + c.s[i + j]) % 10;
c.s[i + j] = tmp2;
k = tmp1;
}
c.s[i + b.len] += k;
}
while(c.len > 1)
{
if(c.s[c.len - 1] == 0)
{
c.len--;
}
else
{
break;
}
}
return c;
}

bign operator += (const bign& b)
{
*this = *this + b;
return *this;
}

bool operator < (const bign& b) const
{
if(len != b.len) return len < b.len;
for(int i = len - 1; i >= 0; i--)
{
if(s[i] != b.s[i])
{
return s[i] < b.s[i];
}
}
return false;
}
};

istream& operator >> (istream &in, bign & x)
{
string s;
in >> s;
x = s.c_str();
return in;
}

ostream& operator << (ostream & out, const bign& x)
{
out << x.str();
return out;
}

int main()
{
bign x1,x2;
while(cin>>x1>>x2)
cout<<x1*x2<<endl;
return 0;
}


模板代码我没加注释,不懂的话可以看看我之后整理的 bign 模板
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息