大三下每日打卡035

792.高精度减法

给定两个正整数(不含前导 00),计算它们的差,计算结果可能为负数。

输入格式

共两行,每行包含一个整数。

输出格式

共一行,包含所求的差。

数据范围

1≤整数长度≤1051≤整数长度≤105

输入样例:

32
11

输出样例:

21
#include <iostream>
#include <vector>
using namespace std;
bool cmp(vector <int> &A,vector <int> &B){ // 判断是否A ≥ B
   if(A.size() != B.size()) return A.size() > B.size(); // 如果A、B长度不相同,长度长的那个数大
   for(int i = A.size() - 1;i >= 0;i --){ // 否则就要从最高位开始看(因为执行这个函数前,A和B数组都已经倒序,所以这里要从后往前看)
       if(A[i] != B[i]) return A[i] > B[i]; // 如果A的当前位和B的当前位不相等,当前位大的更大
  }
   return true; // 如果A、B数组都相等,这里可以直接返回true,当然也可以直接输出0
}
vector <int> sub(vector <int> &A,vector <int> &B){ // A - B
   int t = 0; // 每一位上相减得到的数
   vector <int> C; // 最后的答案
   for(int i = 0;i < A.size();i ++){ // 遍历一遍,和高精度加法不一样的是,只要遍历完A就行了,因为这里A肯定比B长
       t = A[i] - t; // t要等于A的当前位减掉自己,因为上一位有可能出现借位的情况
       if(i < B.size()) t -= B[i]; // 如果没有遍历完B,那么t减掉B的当前位
       C.push_back((t + 10) % 10); // 更新C数组
       // 这里如果没有借位,(t + 10) % 10就刚好等于t
       // 如果这里有借位,(t + 10) % 10就会借一个10下来
       if(t < 0) t = 1; // 如果t < 0,说明不够减,需要借位,把t赋值为1,就是在下一次执行中,A的当前位会减掉t
       else t = 0; // 否则够减,赋值为0,不用借位
  }
   while(C.size() > 1 && C.back() == 0) C.pop_back(); // 删除前导0
   return C; // 返回答案
}
int main(){
   string a,b; // 两个数,因为很大,所以用string来存
   cin>>a>>b; // 读入
   vector <int> A,B; // 两个数,因为减法是从最低位开始减,我们可以把两个数倒过来
   for(int i = a.size() - 1;i >= 0;i --) A.push_back(a[i] - '0'); // 把a数组到过来存入A,记得a是string类型的数组,要减去'0'让它变成数字
   for(int i = b.size() - 1;i >= 0;i --) B.push_back(b[i] - '0'); // 把b数组倒过来存入B
   if(cmp(A,B)){ // 如果A > B
       auto C = sub(A,B); // 那么可以直接相减
       for(int i = C.size() - 1;i >= 0;i --) printf("%d",C[i]); // 最后因为C是倒着的,需要反向输出
  }
   else{ // 否则A < B,需要计算-(B - A)
       auto C = sub(B,A); // 计算B - A
       printf("-"); // 给前面加上一个负号
       for(int i = C.size() - 1;i >= 0;i --) printf("%d",C[i]); // 反向输出C数组
  }
   return 0;
}
 
posted @ 2025-04-14 11:58  软件拓荒人  阅读(21)  评论(0)    收藏  举报