目录
一、算法思想
我们先来看看如何把10进制转化为2进制(网图)
对10进制数反复除2取余数,最后倒序输出的余数序列就是我们需要的二进制序列。怎么理解呢?先来看看我们是怎么理解序列101011的:1*2^0+1*2^1+0*2^2+1*2^3+0*2^4+1*2^5。就和十进制一样每个2进制数都是有权重的,我们在反复除2的过程中剩余的数的权重一直在翻倍,直到余数为0,如这里最下面的1,他代表的权重就是2^5。
转化为k进制也是同样的道理
【核心代码】
while (n)
{
arr[cnt++] = n % k;//用数组记录每次的余数
n /= k;
}
//注意这里得到的序列还需要逆序才是真正的k进制序列
二、405. 数字转换为十六进制数
①题目呈现
405. 数字转换为十六进制数https://leetcode-cn.com/problems/convert-a-number-to-hexadecimal/
思路:因为二进制转换涉及负数,所以我们从二进制的角度切入最为合适。这里一个重要的关系就是二进制4位换十六进制1位
②代码操练
char * toHex(int num)
{
if(num == 0)
return "0";
char* ans = (char*)malloc(sizeof(char) * 9);
char str[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
int a = 0b1111;
int cnt = 0;
while(num)//2进制四位换16进制一位
{
ans[cnt] = str[num & a];
num =(unsigned)num >> 4;
cnt++;
}
int i = 0; int j = cnt - 1;
while(i < j)//字符串反转
{
int tmp = ans[i];
ans[i] = ans[j];
ans[j] = tmp;
i++;j--;
}
ans[cnt] = '\0';
return ans;
}
【易错点】1.注意字符串要以‘\0’结尾,所以malloc开辟空间时要开辟9字节
2.注意强制转换为unsigned再>>,因为有符号-1一直右移仍然是-1
三、Excel列表序号
①题目呈现
这道题目就很简单,是26进制转10进制,按位权重展开即可
②代码操练
int titleToNumber(char * columnTitle)
{
int len =strlen(columnTitle);//计算长度
int ans = 0;
for(int i = 0 ; i < len; i++)
{
ans = ans * 26 ;//(1)
ans += columnTitle[i] - 64; //(2)
}
return ans;
}
【易错点】 (1)(2)两步骤不可以和为ans = ans * 26 + columnTitle[i] - 64,因为计算过程中先算出ans * 26 + columnTitle[i]的值可能会溢出
四、168. Excel表列名称
①题目呈现
168. Excel表列名称https://leetcode-cn.com/problems/excel-sheet-column-title/
思路①:这道题目的难点就在于数字是从1~26而不是从0~25,这使得我们在十进制转二十六进制中时需要“借一位”。
思路②:如何避免借一位呢?上述“借一位”产生的原因在于数字从1开始,所以我们只要使得数字每次运算时-1,那所有的结果都会减小1,完美解决了问题
思路①
void swap(char *a, char *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
char * convertToTitle(int columnNumber)
{
int *num = (int *)malloc( sizeof(int) * 100 );
char *ret = (char *)malloc( sizeof(char) * 100 );
int retSize = 0;
int i;
while(columnNumber)
{
num[ retSize++ ] = columnNumber % 26 - 1;
columnNumber /= 26;
}
num[retSize] = 0;
for(i = 0; i < retSize; ++i)
{
if(num[i]<0)
{
num[i] += 26
num[i+1] -=1
}
}
if(num[retSize] == -1)
{
--retSize;
}
for(i = 0; i < retSize; ++i)
{
ret[i] = num[retSize-1-i] + 'A';
}
ret[retSize] = '\0';
return ret;
}
思路②
char * convertToTitle(int columnNumber)
{
int cnt = 0;
char*str = (char*)malloc(sizeof(char) * 10);
while(columnNumber)
{
columnNumber--;
str[cnt++] = columnNumber % 26 + 'A';
columnNumber /= 26;
}
for(int i = 0; i < cnt / 2; i++)
{
char tmp = str[i];
str[i] = str[cnt - i - 1];
str[cnt - i - 1] = tmp;
}
str[cnt] = '\0';
return str;
}
【易错点】最后的\0不要忘记了