大数减法
头条一面的手撕代码题,第一次手撕代码过于紧张,手都在抖,结果一道愚蠢的模拟题都没在时间里做出来,面试官肯定觉得我水平属实8行了qwq
思路如下,逆序转换成vector数组,预判一下如果是负数就把值都置负,减一个数就是加它的负数嘛,然后全部加起来再处理进位。
最后处理进位时有个坑,首先找到结果中第一个不为0的,判断它的正负性,如果它为负,那么结果就是负数了,处理进位应该处理成负数。为什么第一个不为0的就已经决定了它的正负性了呢?因为后续借位最多为1,即使第一个已经为最小的正整数1了,也还是可以通过当前位置变成0使得后一位变正
面试的时候30分钟没写完,下去了10分钟就写完了,我真是服了自己了
代码如下
#include <bits/stdc++.h>
using namespace std;
vector<int> prefixb(string a) {
vector<int> rnt;
if (a[0] == '-') {
for (int i = a.size() - 1; i > 0; i--) {
rnt.push_back(a[i] - '0');
}
} else {
for (int i = a.size() - 1; i >= 0; i--) {
rnt.push_back(-(a[i] - '0'));
}
}
return rnt;
}
vector<int> prefixa(string a) {
vector<int> rnt;
if (a[0] == '-') {
for (int i = a.size() - 1; i > 0; i--) {
rnt.push_back(-(a[i] - '0'));
}
} else {
for (int i = a.size() - 1; i >= 0; i--) {
rnt.push_back(a[i] - '0');
}
}
return rnt;
}
void solve(string a, string b) {
vector<int> av = prefixa(a);
vector<int> bv = prefixb(b);
vector<int> ans;
int i = 0;
while (av.size() < bv.size()) {
av.push_back(0);
}
while (av.size() > bv.size()) {
bv.push_back(0);
}
for (; i < av.size(); i++) {
ans.push_back(av[i] + bv[i]);
}
ans.push_back(0);
i = ans.size() - 1;
while (i >= 0 && ans[i] == 0) {
i--;
}
if (ans[i] > 0) {
for (int i = 0; i < ans.size() - 1; i++) {
int t = 0;
while (ans[i] < 0) {
t--;
ans[i] += 10;
}
while (ans[i] >= 10) {
t++;
ans[i] -= 10;
}
ans[i + 1] += t;
}
} else {
for (int i = 0; i < ans.size() - 1; i++) {
int t = 0;
while (ans[i] <= -10) {
t--;
ans[i] += 10;
}
while (ans[i] > 0) {
t++;
ans[i] -= 10;
}
ans[i + 1] += t;
}
}
int j = ans.size() - 1;
while (j >= 0 && ans[j] == 0) {
j--;
}
if (j == -1) {
cout << 0 << endl;
} else {
if (ans[j] < 0) {
cout << '-';
}
while (j >= 0) {
cout << abs(ans[j]);
j--;
}
cout << endl;
}
}
int main(void) {
string a;
string b;
cin >> a >> b;
solve(a, b);
return 0;
}