题目:
题目描述 Description
给出两个正整数A和B,计算A-B的值。保证A和B的位数不超过500位。
输入描述 Input Description
读入两个用空格隔开的正整数
输出描述 Output Description
输出A-B的值
样例输入 Sample Input
3 12
样例输出 Sample Output
-9
题目分析
C++整数数据范围:
char -128 ~ +127 (1 Byte)
short
-32767 ~ + 32768
(2 Bytes)
unsigned
short 0 ~ 65536
(2 Bytes)
int
-2147483648 ~ +2147483647 (4 Bytes)
unsigned
int
0 ~ 4294967295 (4 Bytes)
long == int
long long
-9223372036854775808 ~
+9223372036854775807 (8 Bytes)
double
1.7 x 10^308 (8
Bytes)
long long范围最大,能表示19位。Test Case大于20位就会发生溢出的问题,无法计算。
所以题目的数据可以选择用string来储存。
如:string str = “123”;//123 = 1 x 102
+ 2 x 101 + 3 x 100。
指数位 ———— 下标(数的高位与下标高位相反)
系数位 ————
值
为了计算方便,将str转换为int[ ](我习惯用vector).然后用下标和值来进行加减法运算,先得到每一位的值,再进行处理(进位、借位)。
如:
vector<int>
maxv = { 1, 0, 0, 9 } // 1000
vector<int>
maxv = { 2, 3 } // 23
vector<int>
sub, add;
计算后:sub = {
1, 0, -2, 6 };
add = {
1, 0, 2, 12 };
处理后 : sub =
{ 0, 8, 8, 6 } // 小于0,借位
add = { 1, 0,
3, 2 } // 小于0,进位
输出:注意处理0。
减法:
n
计算:统一用大数减小数,如果输入被减数小于减数,交换它们,标记输出为负。按位相减即可,从低位高位皆可。
n
转换:高位借位-1,本位+10变为正,依次循环。
加法与减法类似。
乘法,用两个循环,依次相乘做和,更新每一位的值。
这个算式是从数值高位开始算的(直接从vector
0开始),当然也可以按普通乘法计算从低位开始。然后再进行进位转换,注意大于100和大于10的进位。
/*
高精度减法法题目: http://codevs.cn/problem/3115/
2015.5.5 shaonian.ding
*/
#include<iostream>
#include<vector>
#include<string>
usingnamespace std;
//string convert to vector<int> function
void strToInts(string str, vector<int>
&v){
int len = str.size();
for (int i = 0;
i < len; i++)
{
int c = str[i] - ‘0‘;
v.push_back(c);
}
}
int main(){
string maxStr,
minStr;//被减数,减数string.
/*test
case*/
//maxStr
= "1000";
//minStr
= "10";
/*Input
Data*/
cin
>> maxStr>>minStr;
/*code*/
vector<int>
maxv,minv;//max vector、min
vector
bool
isPositive = true;//差正负标记,用来最后输出
//如果减数小于被减数,交换位置他们。差标记为负数,isPositive
= false;
if
(maxStr.size() <= minStr.size()){
if
(maxStr.size() == minStr.size()){
for (int i = 0;
i < maxStr.size(); i++)
{
if
(maxStr[i] < minStr[i]){
swap(maxStr,
minStr);
isPositive
= false;
break;
}
}
}
else{
swap(maxStr,
minStr);
isPositive
= false;
}
};
//string
convert to ints
strToInts(maxStr,
maxv);
strToInts(minStr,
minv);
//maxv =
maxv - minv;高位开始减,得到序列max =
{1,0,-1,0}
for (int i = 0;
i < minv.size(); i++)
{
int j =
maxv.size() - minv.size()+i;
if
(i<minv.size()){
maxv[j]
= maxv[j] - minv[i];
}
}
//将包含负数的序列按借位方法变为正。max =
{0,9,9,0}
for (int i =
maxv.size()-1; i > 0; i--)
{
if
(maxv[i] < 0){
maxv[i]
+= 10;
maxv[i
- 1] -= 1;
}
}
/*输出*/
if
(!isPositive){
cout
<< "-";
}
if
(maxv[0] != 0){
cout
<< maxv[0];
}
for (int i = 1;
i < maxv.size(); i++)
{
cout
<< maxv[i];
}
return 0;
}
加法:
/*
高精度加法题目:http://codevs.cn/problem/3116/
2015.5.5 shaonian.ding
*/
#include<iostream>
#include<vector>
#include<string>
usingnamespace std;
//string convert to vector<int> function
void strToInts(string str, vector<int>
&v){
int len = str.size();
for (int i = 0;
i < len; i++)
{
int c = str[i] - ‘0‘;
v.push_back(c);
}
}
int main(){
string maxStr,
minStr;
/*test
case*/
//maxStr = "945";
//minStr = "59";
/*Input
Data*/
cin
>> maxStr >> minStr;
/*code*/
vector<int>
maxv, minv;//max vector、min
vector
if
(maxStr.size() <= minStr.size()){
swap(maxStr,
minStr);
};
//string
convert to ints
strToInts(maxStr,
maxv);
strToInts(minStr,
minv);
//maxv =
maxv - minv;高位开始加,得到序列max =
{9,9,14}
for (int i = 0;
i < minv.size(); i++)
{
int j =
maxv.size() - minv.size() + i;
maxv[j]
= maxv[j] + minv[i];
}
//max =
{9,9,14}
for (int i =
maxv.size() - 1; i > 0; i--)
{
if
(maxv[i] >= 10){//最多为19
maxv[i]
-= 10;
maxv[i
- 1] += 1;//i=1执行最后一次转换,maxv[0]可能等于10
}
}
/*输出*/
if
(maxv[0] != 10){//跳过最高位为0
cout
<< maxv[0];
}
else{
cout
<< "1" << 10 - maxv[0];
}
for (int i = 1;
i < maxv.size(); i++)
{
cout
<< maxv[i];
}
return 0;
}
乘法:
/*
高精度乘法题目:http://codevs.cn/problem/3117/
2015.5.5 shaonian.ding
*/
#include<iostream>
#include<vector>
#include<string>
usingnamespace std;
//string convert to vector<int> function
void strToInts(string str, vector<int>
&v){
int len = str.size();
for (int i = 0;
i < len; i++)
{
int c = str[i] - ‘0‘;
v.push_back(c);
}
}
int main(){
string maxStr,
minStr;
/*test case */
//maxStr = "123";
//minStr = "45";
//maxStr = "99";
//minStr = "99";
/*Input
Data*/
cin
>> maxStr >> minStr;
/*code*/
vector<int>
maxv, minv;//max vector、min
vector
//string
convert to ints
strToInts(maxStr,
maxv);
strToInts(minStr,
minv);
int n =
maxv.size() + minv.size();//乘积的位数(不会大于两乘数位数之和)。
vector<int>
mul(n, 0 );//保存乘积multiplication,用来输出。
/*
*tset1:mul
={ 0,4,13,22,15 }
*tset2:mul
={ 0,81,162,81}
*/
for (int i = 0;
i < minv.size(); i++)// min i 外循环
{
for (int j = 0;
j < maxv.size(); j++)//max j 内循环
{
mul[i
+ j+1] += maxv[j] * minv[i];//
}
}
/*
*test1:mul
= { 0,5,5,3,5 }
*test2:mul
= { 9,8,0,1 }
*/
for (int i =
mul.size() - 1; i > 0; i--)
{
if (mul[i]
>= 100){//最多为199
mul[i
- 1] += mul[i] / 10;//进位
mul[i]
-= mul[i] / 10 *10;
}elseif (mul[i]
>= 10){//最多为99
mul[i
- 1] += mul[i] / 10;
mul[i] -=
mul[i] / 10 * 10;
}
}
/*输出*/
if (mul[0]
!= 0){//跳过最高位为0
cout
<< mul[0];
}
for (int i = 1;
i < mul.size(); i++)
{
cout
<< mul[i];
}
return 0;
}