负进制转换

负进制转换

之前某技术面原题,怎么把一个十进制数12转换为负3进制,今天心血来潮在leetcode搜了下发现确实有原题而且我好像还是不会做的亚子。
传送门如下:
https://leetcode-cn.com/problems/convert-to-base-2/
看明白之后尝试写了一下这个题目的思路:
一般正数的进制转换代码是这样的↓

int trans(int num,int ratio)
{
	int res = 0;
	int rem = 0;//余数
	int i = 0;
	while(num!=0)
	{
		rem = num % ratio;//得到余数
		num -= rem;//减去余数之后为除数的整数倍
		num /= ratio;//然后得到商
		res += rem * pow(10,i);//这里使用的是输出int型,下面LeetCode是因为题目给的返回string,因为都想尝试一下就没有改了。
		i++;
	}
	return res;
}

然后把负进制带进去试了一下,可以发现如果
12/(-3) = -4…0
-4/(-3) = 2…2
2/(-3) = 0…2
因为商为0了所以这个时候停止循环,得到结果就是220,答案正确。
也就是说,如果得到的余数一直都是正数的话,之前的正数进制其实是可以用的。

经过尝试发现m%n取余符号其实是往下取余的,当m为负数时候比如说(-1)%(-2) = 0…-1
而不是(-1)%(-2) = 1…1,也就是让商尽可能小
emm大概这就是负进制的难点了吧
所以,关键步骤就是把余数变为正的!

参考了个大神做法最后得到解答如下:

int main()
{
	int N = 12;
	string res;//结果
	int rem = 0;//余数
	int i = 0;
	while (N != 0)
	{
		rem = (N % (-3) + abs(-3)) % (-3);//其实就是说(-1)/(-2)=0...-1的话,那就让它往上取余变成(-1)/(-2)=1....1
		N -= rem;
		N /= (-3);
		res += to_string(rem);
		i++;
	}
	string res_res;
	for (int j = 0; j<res.length(); j++)
	{
		res_res += res[res.length() - 1 - j];
		//之前用的res_res[j] = res[res.length() - 1 - j]...然后vs给中断了好多次说数组超了,最后得出结论string还是不要直接赋值好,原理还没搞明白(对的我就是觉得没有啥语法错误。。),希望有懂的小伙伴可以帮个忙
	}
	cout << res_res;
	return 0;
}

输出答案为220,其他进制尝试也没有问题
也算是了了一个心结。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值