前言
题目就咱就不叙述了,直接开整!!!
首先呢,我们先来想一下十进制的加法是怎样运算的,是不是这样的
从低位算着走,满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()函数,字符和数字之间的互相转换
博主第一次写博客,写的菜的地方,还望大家海涵,
欢迎大家在评论区留言和讨论