计算两个非负整数 的乘积, 可能会很大。
输入格式
第一行输入一个非负整数 。
第二行输入一个非负整数 。
的长度不大于 。
输出格式
输出 的值。
样例输入
4321
1234
样例输出
5332114
解:
1.长度小于等于500的非负整数,longlong型肯定是满足不了的,像A+B问题中使用string来操作又过于麻烦,得多次考虑字符型与整型的互换,因此我考虑用向量类vector来操作,动态分配空间大小。
string刚好能把从键盘上输入的字符一个个存储,这时字符与vector 的转换只用进行一次即可。
(大段注释是另一种输入方法要用头文件conio,但输入后屏幕上没反馈)
2.数相乘不免会涉及到进位,直接存储时最高位在最左边,用reverse函数反转后方便添加进位(push_back()),但最后输出时得留心。
3.相乘结果需用新的变量存储,我实在想不到不使用新变量存储的办法。
4.乘法举例,1234
4321=1234
1+1234
20+1234
300+1234
4000,而保存的数只能一位一位相乘,乘出来的结果保存的位置有个规律:被拆开数的最高位依次与完整数一位位相乘后保存在被拆开的数的最高位起的后面几位,语言描述生涩,举例说明:1234
20中20的最高位为十位,4
2后保存在是十位,3
2保存在百位,2
2保存在千位,1
2保存在万位。 代码中我用temp保存被拆开数的最高位。
保存时注意,当前位置是否存在。
5.计算完再从低位到高位清理进位。
代码
#include"iostream"
#include"vector"
#include"string"
#include"algorithm"
//#include"conio.h"//计蒜客的OJ用不了这个
using namespace std;
int main()
{
vector<int> a,b,c;
/*
char t;
while(t=getch())//输入a但不显示
if(t=='\r')break;
else a.push_back(t-48);
while(t=getch())//输入b
if(t=='\r')break;
else b.push_back(t-48);
*/
string s1,s2;
cin>>s1>>s2;//输入stirng转换为vector<int>
for(int i=0;i<s1.length();i++)
a.push_back(s1[i]-48);
for(int i=0;i<s2.length();i++)
b.push_back(s2[i]-48);
//反转
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
//相乘
int temp=0;//保存被拆开数的最高位
for(int i=0;i<a.size();i++)
{
temp=i;
for(int j=0;j<b.size();j++)
{
if(temp>=c.size())
c.push_back(a[i]*b[j]);
else
c[temp]+=a[i]*b[j];
temp++;
}
}
//遍历消除进位
for(int i=0;i<c.size();i++)
{
if(c[i]>9)//如果当前位大于9
{
if(i==c.size()-1)//进位是最高位
c.push_back(c[i]/10);
else
c[i+1]+=(c[i]/10);
c[i]=c[i]%10;
}
}
//反转回来
reverse(c.begin(),c.end());
if((a.size()==1&&a[0]==0)||(b.size()==1&&b[0]==0))//0为乘数的情况
{//不然会输出多个0
cout<<0;
return 0;
}
for(int i=0;i<c.size();i++)//结果输出
cout<<c[i];
return 0;
}