输入一个以#结束的字符串,本题要求滤去所有的非十六进制字符(不分大小写),组成一个新的表示十六进制数字的字符串,然后将其转换为十进制数后输出。如果在第一个十六进制字符之前存在字符“-”,则代表该数是负数。
输入格式:
输入在一行中给出一个以#结束的非空字符串。
输出格式:
在一行中输出转换后的十进制数。题目保证输出在长整型范围内。
输入样例:
+-P-xf4+-1!#
输出样例:
-3905
>_code
#include <stdio.h>
#include <string.h>
#include <math.h>
#define N 50
char *get_x_str(char *str);
long get_d_str(char *str);
int main(int argc, char const *argv[])
{
int i = 0;
char str[N] = "";
while((str[i++]=getchar())!='#');//注意优先级,先赋值,再i+1,再比较
str[--i] = '\0';
//puts(get_x_str(str));//test
printf("%ld\n",get_d_str(get_x_str(str)));
return 0;
}
//滤去非十六进制字符(不分大小写)
char *get_x_str(char *str)
{
char *move = str;
char *p = NULL;
char *next = NULL;
int flag = 0;
while(*move!='\0')
{
p = move;
//十六进制:0~9、a~f、A~F、保留第一个十六进制字符之前存在的字符“-”
if((*p>='0' && *p<='9')||(*p>='a' && *p<='f')||(*p>='A' && *p<='F')||(0==flag && *p=='-'))
{
flag++;
move++;//当前位置是十六进制时才往后偏移一位
}
else
{
next = p+1;
//后面字符整体往前移一位,覆盖当前位置非十六进制字符
while (*next!='\0')
{
*p = *next;
p++;
next++;
}
*p = '\0';
next = NULL;
}
}
return str;
}
//十六进制字符串转十进制整数
long get_d_str(char *str)
{
int i,sum = 0,flag = 0;
int length = strlen(str);
char *p = str+length-1;
if(*str!='-')
flag = 1;
else
length--;
for(i=0;i<length;i++)
{
if(*p>='A'&&*p<='Z')
*p = *p-55;
else if(*p>='a'&&*p<='z')
*p = *p-87;
else if(*p>='0'&&*p<='9')
*p = *p-48;
//printf("i=%d *p=%c %d\n",i,(*p),__LINE__);//test
//printf("i=%d *p=%d %d\n",i,(long)(*p),__LINE__);//test
sum += (long)(*p)*pow(16,i);
//printf("i=%d sum=%ld %d\n",i,sum,__LINE__);//test
p--;
}
return 1==flag?sum:-sum;
}
总结
1.十六进制--->十进制
假设有一个十六进数 AF5
用竖式计算:
AF5换算成十进制:
第0位:$5×16^0 = 5$
第1位:$F×16^1 = 15×16^1 = 240$
第2位:$A×16^2 = 10×16^2 = 2560$
直接计算就是:$5×16^0+F×16^1+A×16^2 = 2805$
2.十进制--->十六进制
假设有一个十进制数 120--->十六进制数 78
120 ÷ 16,得到商是7,余数是8
7 ÷ 16,得到商是0,余数是7
计算:将商继续除以16,直到商为0,将所有余数倒序排列
3.ascii码字符--->十进制
对字符强制转换成对应的十进制数
'0'~'9'--->48~57
'A'~'Z'--->65~90
'a'~'z'--->97~122
其余整数可在以上基础上对ascii字符进行加减后再强制转换
本文链接:https://shengto.top/c/pat_55.html
转载时须注明出处及本声明