刷题笔记-24进制加减法函数

题目描述

如题

解题思路

手写加减法最重要的就是捋清进位和借位的逻辑,其实就是模拟算式运算。

  • 加法的处理思路是将加数1当前位 + 加数2当前位 + 进位,用得到的数值 mod 进制得到当前位的计算结果,再判断是否有进位。
  • 减法的思路是用被减数的当前位 - 借位 - 减数的当前位,如果 (被减数 - 借位) 小于 减数当前位,则产生借位,当前位的计算结果是 借位后的数值 - 减数当前位。
  • 在处理减法时,可以选择用大数减小数,得到的结果再取反。下面的程序是基于字符串实现的,取反就是在字符串首部添加 ‘-’。
  • 再考虑输入的数字有可能为负数,那么有如下的情况(假设 a 和 b都为正数):
//加法
a + b = a + b;
a + (-b) = a - b; //用减法计算加法
(-a) + b = b - a;//同上
(-a) + (-b) = -(a + b);//最后添加‘-’
//减法
a - b = a - b;
a - (-b) = a + b;//用加法计算减法
(-a) - b = -(a + b);//同上
(-a) - (-b) = b - a;

实现

代码写的应该有点臃肿,没做进一步精简。
测试了几个自己想的测试用例是可以通过的,测试用例的格式示例:-4nm + 5nn(注意空格)或者 -4nm - 5nn

# include<iostream>
# include<string>
# include<algorithm>
using namespace std;
int scale = 24;

string myplus(string& a,string& b);
string mysub(string& a, string& b);
int convert(char x);//字符转整型数字
char rconvert(int x);//整型数字转字符,0-23 -> 0-9 & a-n
bool bigger(string str1, string str2);

int convert(char x)
{
	if (x >= '0' && x <= '9')
		return x - '0';
	else{
		return x - 'a' + 10;
	}
}

char rconvert(int x)
{
	if (x <= 9)
		return '0' + x;
	else
		return 'a' + x - 10;
}

bool bigger(string str1, string str2){//str1是否大于str2
	size_t s1len = str1.length(), s2len = str2.length();
	if (s1len > s2len)
		return true;
	else if (s1len == s2len)
		return str1 > str2;
	else return false;
}

string myplus(string& a, string& b)
{
	string res;
	if (a[0] == '-' && b[0] == '-')//(-a)+(-b)=-(a+b)
	{
		res = myplus(a.substr(1, a.length() - 1), b.substr(1, b.length() - 1));
		res.insert(0, 1, '-');
	}
	else if (a[0] == '-' || b[0] == '-')//a+(-b)=a-b, (-a)+b=b-a;
	{
		if (a[0] == '-'){
			a = a.substr(1, a.length() - 1);
			res = mysub(b, a);
		}
		else if (b[0] == '-'){
			b = b.substr(1, b.length() - 1);
			res = mysub(a, b);
		}
	}
	else{//a和b都是正数
		size_t alen = a.length(), blen = b.length(), srt = min(alen, blen), lng = max(alen, blen), i;
		string &tem = b;
		if (alen > blen)
			tem = a;
		int flag = 0;
		char c;
		for (i = 0; i < srt; ++i){
			int end = convert(a[alen - 1 - i]) + convert(b[blen - 1 - i]) + flag;
			if (end >= scale)
			{
				c = rconvert(end - scale);
				flag = 1;
			}
			else{
				c = rconvert(end);
				flag = 0;
			}
			res.insert(0, 1, c);
		}
		for (i = srt; i < lng; ++i)
		{
			res.insert(0, 1, rconvert((convert(tem[lng -srt-1]) + flag) % scale));
			flag = (convert(tem[lng - srt - 1]) + flag) / scale;
		}
		if (flag != 0) res.insert(0, 1, rconvert(flag));
	}
	
	return res;
}

string mysub(string& a, string& b){//注意最高位是0的情况
	string res;
	if (a[0] == '-' && b[0] == '-'){//(-a)-(-b)=b-a
		a = a.substr(1, a.length() - 1);
		b = b.substr(1, b.length() - 1);
		res = mysub(b, a);
	}
	else if (a[0] == '-' || b[0] == '-'){//a-(-b)=b+a, (-a)-b = -(a+b);
		if (a[0] == '-'){
			a = a.substr(1, a.length() - 1);
			res = myplus(a, b);
			res.insert(0, 1, '-');
		}
		else if (b[0] == '-'){
			b = b.substr(1, b.length() - 1);
			res = myplus(a, b);
		}
	}
	else{//a和b都是正数
		bool isneg = true;
		if (bigger(b, a)) {
			isneg = false;
			res = mysub(b, a);
			res.insert(0, 1, '-');
		}
		else{//a和b都是正数且a>b
			int flag = 0;
			size_t s2len = b.length(), s1len = a.length();
			size_t srt = s2len, lng = s1len, big, sma, i;
			char c;
			for (i = 0; i < srt; ++i)
			{
				big = convert(a[s1len - 1 - i]) - flag;
				sma = convert(b[s2len - 1 - i]);
				if (big >= sma)//有可能为0
				{
					flag = 0;
					c = rconvert(big - sma);
				}
				else if (big < sma)
				{
					flag = 1;
					c = rconvert(big + scale - sma);
				}
				res.insert(0, 1, c);
			}
			for (i = srt; i < lng; ++i)
			{
				big = convert(a[s1len - 1 - i]) - flag;
				flag = 0;
				res.insert(0, 1, rconvert(big));
			}
			i = 0;
			while (i < res.length() && res[i] == '0') ++i;
			if (i == res.length()) res = "0";
			else{
				res = res.substr(i, res.length() - i);
			}
		}
	}
	return res;
}

int main(){
	string str1, op, str2, rest;
	while (cin >> str1 >> op >> str2){
		if (op == "+")
			rest = myplus(str1, str2);
		else if (op == "-")
			rest = mysub(str1, str2);
		else{
			cout << "operator invalid" << endl;
			continue;
		}
		cout << rest << endl;
	}
	system("pause");
}

废话

之前做笔试的时候紧张得思维混乱,现在克服了笔试时的紧张情绪,可以专注想问题了。但还是过不了面试的手撕代码关,emm,什么时候再进阶一下。
就在此处悄咪咪表白一下 Ali 的面试官,他们都是大可爱!感恩,手动比心。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值