人类习惯用 10 进制,可能因为大多数人类有 10 根手指头,可以用于计数。这个世界上有一种叫“钱串子”(学名“蚰蜒”)的生物,有 30 只细长的手/脚,在它们的世界里,数字应该是 30 进制的。本题就请你实现钱串子世界里的加法运算。
输入格式:
输入在一行中给出两个钱串子世界里的非负整数,其间以空格分隔。
所谓“钱串子世界里的整数”是一个 30 进制的数字,其数字 0 到 9 跟人类世界的整数一致,数字 10 到 29 用小写英文字母 a 到 t 顺次表示。
输入给出的两个整数都不超过 10^5 位。
输出格式:
在一行中输出两个整数的和。注意结果数字不得有前导零。
输入样例:
2g50ttaq 0st9hk381
输出样例:
11feik2ir
解题思路:
采用模拟竖式计算的方式来写就行,另外就是要注意两数相加为0的情况、数字与字符间的转换问题就行
Tips:建议不要去背所谓的字符串竖式计算的代码模板,其实根本不用背,在下面的代码你会很清晰的明白字符串竖式计算的代码该怎么写
有注释代码示例:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//字符转数字
int getNum(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
return c - 'a' + 10;
}
//数字转字符
char getChar(int num) {
if (num >= 0 && num <= 9) {
return num + '0';
}
return num - 10 + 'a';
}
int main() {
string s1, s2;
cin >> s1 >> s2;
//竖式计算的第一步,得到两数的最大长度len 以题目样例为例 len为9
int len = max(s1.length(), s2.length());
//竖式计算的第二步,创建最大长度加1的数组并初始化为0
//因为两数相加的结果的长度最大也就是最大长度len+1
vector<int> ans(len + 1, 0); //ans的大小为10
//竖式计算的第三步,模拟计算过程 初始情况k=8
for (int i = s1.length() - 1, j = s2.length() - 1, k = len - 1; k >= 0; i--, j--, k--) {
//当从右往左开始计算时i无法递减时用0去代替
int num1 = (i >= 0) ? getNum(s1[i]) : 0;
//当从右往左开始计算时j无法递减时用0去代替
int num2 = (j >= 0) ? getNum(s2[j]) : 0;
//求和,求的是每位数之和并加上进位,k+1=9 从ans的最后一位开始计算
//在每一次循环过程中ans[k + 1]会得到ans[k]的进位
int sum = ans[k + 1] + num1 + num2;
//填入结果
ans[k + 1] = sum % 30;
//向前进位 k=8,ans最后一位的前一位
ans[k] += sum / 30;
//k--过程中循环往复如此计算即可,把30换成10就变成了十进制的竖式计算
}
bool flag = false; //结果的前面是否有连续的0的标志
for (int i = 0; i < ans.size(); i++) {
if (ans[i] == 0 && !flag) {
continue;
}
flag = true; //代表连续的0已经略过,可以正常往后输出了
cout << getChar(ans[i]);
}
if (!flag) { //代表连续的0始终没有略过,表明ans里面全为0.即两数之和为0
cout << "0";
}
return 0;
}
无注释代码示例:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//字符转数字
int get_num(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
return c - 'a' + 10;
}
//数字转字符
char get_char(int n) {
if (n >= 0 && n <= 9) {
return n + '0';
}
return n - 10 + 'a';
}
int main() {
string a, b;
cin >> a >> b;
int lena = a.length(), lenb = b.length();
int len = max(lena, lenb);
vector<int> ans(len + 1, 0);
for (int i = lena - 1, j = lenb - 1, k = len - 1; k >= 0; i--, j--, k--) {
int numa = (i >= 0) ? get_num(a[i]) : 0;
int numb = (j >= 0) ? get_num(b[j]) : 0;
int sum = ans[k + 1] + numa + numb;
ans[k + 1] = sum % 30;
ans[k] += sum / 30;
}
bool flag = false; //数的前面是否有连续的0的标志
for (int i = 0; i <= len; i++) {
if (!flag && ans[i] == 0) {
continue;
}
flag = true; //代表连续的0已经略过,可以正常往后输出了
cout << get_char(ans[i]);
}
if (!flag) { //代表连续的0始终没有略过,代表ans里面全为0.即结果为0
cout << "0";
}
return 0;
}