Excel列转十进制
例如
A -> 1
B -> 2
C -> 3
...
Z -> 26
AA -> 27
AB -> 28
思路:本质是一个26进制数转十进制的问题,求这类问题都是从高位到低位遍历,就是正常遍历字符串,在遍历当前值时,对上一个值乘以进制数。举个例子:
BAD,初始结果res为0,
->B, res = 0 * 26 + 2 = 2;
->A, res = 2 * 26 + 1 = 53;
->D, res = 53 * 26 + 4 = 1382;
如果换成16进制,把26改成16,字母对应10进制值就可以了
int titleToNumber(char* s) {
int res = 0;
while(*s){
res = res * 26 + *s - 'A' + 1;
s++;
}
return res;
}
罗马数字转十进制
罗马数字 | I | V | X | L | C | D | M |
---|---|---|---|---|---|---|---|
阿拉伯数字 | 1 | 5 | 10 | 50 | 100 | 500 | 1000 |
- 相同的数字连写、所表示的数等于这些数字相加得到的数、如:Ⅲ=3;
- 小的数字在大的数字的右边、所表示的数等于这些数字相加得到的数、 如:Ⅷ=8、Ⅻ=12;
- 小的数字、(限于 Ⅰ、X 和 C)在大的数字的左边、所表示的数等于大数减小数得到的数、如:Ⅳ=4、Ⅸ=9;
- 正常使用时、连写的数字重复不得超过三次;
- 在一个数的上面画一条横线、表示这个数扩大 1000 倍。
int romanToInt(char* s) {
int size = strlen(s);
int res = 0;
for(int i = size - 1; i >= 0; i--){
switch(s[i]){
case 'I':
res += (res >= 5) ? -1 : 1;
break;
case 'V':
res += 5;
break;
case 'X':
res += 10 * (res >= 50 ? -1 : 1);
break;
case 'L':
res += 50;
break;
case 'C':
res += 100 * (res >= 500 ? -1 : 1);
break;
case 'D':
res += 500;
break;
case 'M':
res += 1000;
break;
}
}
return res;
}
十进制转16进制
思路:线性思考,一个整型由32/64位组成,这里只考虑32位,16进制是每四位为一个数字符号,这样每四位都与(&)0xf,即num&15,就可以求得一位16进制,负数的话要转化成无符号数,否则右移的话左侧一直补1,例如-1的二进制为1111 1111,右移永远为-1,实际上我们应该转化为ff
char* toHex(int num) {
unsigned int n = num;//转化为无符号数很关键
if(n == 0)
return "0";
char* res = (char*)malloc(9);
res[8] = 0;
int tmp = 0;
int i = 7;
while(n != 0){
tmp = n & 15;
if(tmp < 10){
res[i] = tmp + '0';
}else{
res[i] = tmp - 10 + 'a';
}
n = n >> 4;
i--;
}
return res + i + 1;//由于是从末尾开始往数字高位递推,res申请的空间未必都能用完,因此需要移动指针
}