[解题报告]《算法零基础100讲》(第20讲) 进制转换(二) – 进阶参考题解(C语言实现)

目录

 一、算法思想

 二、405. 数字转换为十六进制数

 三、Excel列表序号

 四、168. Excel表列名称


 

 一、算法思想

我们先来看看如何把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. 数字转换为十六进制数icon-default.png?t=LA46https://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] = '';
    return ans;
}

 【易错点】1.注意字符串要以‘’结尾,所以malloc开辟空间时要开辟9字节

                  2.注意强制转换为unsigned再>>,因为有符号-1一直右移仍然是-1

 三、Excel列表序号

①题目呈现

171. Excel 表列序号https://leetcode-cn.com/problems/excel-sheet-column-number/icon-default.png?t=LA46https://leetcode-cn.com/problems/excel-sheet-column-number/

 

 这道题目就很简单,是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表列名称icon-default.png?t=LA46https://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] = '';             
    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] = '';
    return str;
}

【易错点】最后的不要忘记了

 

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>