PTA 1113 钱串子的加法 C++实现 简练代码

人类习惯用 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;
}

运行结果:

猜你喜欢

转载自blog.csdn.net/m0_53209892/article/details/129903950