36进制的加法(C语言版)


前言

题目就咱就不叙述了,直接开整!!!
在这里插入图片描述

首先呢,我们先来想一下十进制的加法是怎样运算的,是不是这样的
从低位算着走,满10进1,把其余数留下来,举个特例在这里插入图片描述
3+9大于10了吧那么他就应该向前进(3+9)/10,在%10得到2以此来作为个位的值,同理对于十位则应是(2+1+1)%10,商为0,向前进0,(2+1+1)%10=4,则十位就应为4,依次类推,得到最终结果142;
以此思想我们来解决36进制的加法;


一、10-35怎么表示?

我们知道a=10,b=11…可是我们应该如何表示出来呢?
根据:ASCLL码表的排版可知是不是有0+’0‘=’0‘,1+’0‘=’1‘…
int n;(0=<n<=9)则有n+‘0’=‘n’;
同理char n;(‘a’=<n<=‘z’),则有n-’a‘+10=x
举个特例:char n=’c‘;根据公式是不是有x=12
是不是就代表着’c‘就代表着12,同理可以a,b…是不是都得以表示了
那我们直接根据这个公式写成两个函数就行了

int getInt(char n)//将'0'-'9'转换为0-9;'a'-'z'转换成10-35
{
	if (n >= '0' && n <= '9')
		return n - '0';
	else
	{
		return n - 'a' + 10;
	}
}

char getChar(int n)//将0-9转换为'0'-'9';a-z转换成’a'-‘z'
{
	if (n >= 0 && n <= 9)
		return n + '0';
	else
		return n - 10 + 'a';
}

二、操作代码

定义一个全局数组res来记录最终的结果
首先我们要计算出两个字符数组的长度(判断哪个字符数组先走完)
然后我们从c1和c2的低位开始相加
再相加之前呢,我们都首先把c1[i]和c2[j]转换为10进制数
直接调用getInt()函数就行了
最终计算出低位的值,再调用getChar(),将低位的值转变为用字符表示就行了,并把其放在res[k]里面
后面以次进行
如果是c1想结束,则以下就是c2单独循环以上步骤
如果是c2想结束,则以下就是c1单独循环以上步骤
最后res数组里面保存的是我们想要的结果的逆置
所以我们最后再将其局部逆置一下就行l

char* Add36(char* c1, char* c2)
{
	int len1 = (int)strlen(c1);
	int len2 = (int)strlen(c2);
	char* res = (char*)calloc((len1+len2+1),sizeof(char));
	if (!res)
		exit(EXIT_FAILURE);
	int i = len1 - 1;
	int j = len2 - 1;
	int tail = 0;
	int k = 0;
	while (j > -1 && i > -1)
	{
		int x = getInt(c1[i]);
		int y = getInt(c2[j]);
		int tmp = (x + y + tail) % 36;//余数作为低位结果
		tail = (x + y + tail) / 36;//商的话作为进位
		res[k] = getChar(tmp);
		j--;
		--i;
		k++;
	}
	while (j > -1)//c1里面的元素走完了,c2里面还有剩余
	{
		int y = getInt(c2[j]);
		int tmp = (y + tail) % 36;//余数作为低位结果
		tail = (y + tail) / 36;//进位
		res[k] = getChar(tmp);
		j--;
		k++;
	}
	while (i > -1)//c2里面的元素走完了,c1里面还有剩余
	{
		int x = getInt(c1[i]);
		int tmp = (x + tail) % 36;//余数作为低位结果
		tail = (x + tail) / 36;//进位
		res[k] = getChar(tmp);
		i--;
		k++;
	}
	while (tail)//c1、c2都走完了,但是还有进位,要把进位算起
	{
		int tmp = (tail) % 36;//余数作为低位结果
		tail = (tail) / 36;//进位
		res[k] = getChar(tmp);
		k++;
	}
	My_reverse(res, 0,k-1);//最后的话将局部元素转置一下;
	return res;
}

字符逆置函数:

void My_reverse(char* res,int left,int right)
{
	while (left < right)
	{
		char tmp = res[left];
		res[left] = res[right];
		res[right] = tmp;
		left++;
		right--;
	}
}

三、整体代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#pragma warning (disable:4996)//这个是忽略VS2019报的警告,如果是其他编译器可以不要这句;
int getInt(char n)//将'0'-'9'转换为0-9;'a'-'z'转换成10-35
{
	if (n >= '0' && n <= '9')
		return n - '0';
	else
	{
		return n - 'a' + 10;
	}
}

char getChar(int n)//将0-9转换为'0'-'9';a-z转换成’a'-‘z'
{
	if (n >= 0 && n <= 9)
		return n + '0';
	else
		return n - 10 + 'a';
}
void My_reverse(char* res,int left,int right)
{
	while (left < right)
	{
		char tmp = res[left];
		res[left] = res[right];
		res[right] = tmp;
		left++;
		right--;
	}
}
char* Add36(char* c1, char* c2)
{
	int len1 = (int)strlen(c1);
	int len2 = (int)strlen(c2);
	char* res = (char*)calloc((len1+len2+1),sizeof(char));
	if (!res)
		exit(EXIT_FAILURE);
	int i = len1 - 1;
	int j = len2 - 1;
	int tail = 0;
	int k = 0;
	while (j > -1 && i > -1)
	{
		int x = getInt(c1[i]);
		int y = getInt(c2[j]);
		int tmp = (x + y + tail) % 36;//余数作为低位结果
		tail = (x + y + tail) / 36;//商的话作为进位
		res[k] = getChar(tmp);
		j--;
		--i;
		k++;
	}
	while (j > -1)//c1里面的元素走完了,c2里面还有剩余
	{
		int y = getInt(c2[j]);
		int tmp = (y + tail) % 36;//余数作为低位结果
		tail = (y + tail) / 36;//进位
		res[k] = getChar(tmp);
		j--;
		k++;
	}
	while (i > -1)//c2里面的元素走完了,c1里面还有剩余
	{
		int x = getInt(c1[i]);
		int tmp = (x + tail) % 36;//余数作为低位结果
		tail = (x + tail) / 36;//进位
		res[k] = getChar(tmp);
		i--;
		k++;
	}
	while (tail)//c1、c2都走完了,但是还有进位,要把进位算起
	{
		int tmp = (tail) % 36;//余数作为低位结果
		tail = (tail) / 36;//进位
		res[k] = getChar(tmp);
		k++;
	}
	My_reverse(res, 0,k-1);//最后的话将局部元素转置一下;
	return res;
}

四、测试结果

在这里插入图片描述

在这里插入图片描述

时间复杂度:O(N)
空间复杂度:O(1),这里不包括存储结果所花费的空间;

总结

主要是实现getInt()函数和getChar()函数,字符和数字之间的互相转换
博主第一次写博客,写的菜的地方,还望大家海涵,
欢迎大家在评论区留言和讨论
在这里插入图片描述

  • 17
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南猿北者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值