输入一个以#结束的字符串,本题要求滤去所有的非十六进制字符(不分大小写),组成一个新的表示十六进制数字的字符串,然后将其转换为十进制数后输出。如果在第一个十六进制字符之前存在字符“-”,则代表该数是负数。
输入格式:
输入在一行中给出一个以#结束的非空字符串。
输出格式:
在一行中输出转换后的十进制数。题目保证输出在长整型范围内。
输入样例:
+-P-xf4+-1!#
输出样例:
-3905
我的解法:
#include<stdio.h> //挺麻烦的,但自认为是比较工整的!已发布CSDN
#include<string.h>
#include<math.h>
void Remove_InvalidSympol(char a[],int n){ //去除无效字符
char valid_sympol[]={'-','0','1','2','3','4','5','6','7','8','9','a','A','b','B','c','C','d','D','e','E','f','F'};
int len_right_symbol=strlen(valid_sympol);
int cnt=0;
char temp[1000];
for(int i=0;i<n;i++){
int isinright=0;
for(int j=0;j<len_right_symbol;j++){
if(a[i]==valid_sympol[j]){
isinright=1;
break;
}
}
if(isinright){
temp[cnt]=a[i];
cnt++;
}
}
strcpy(a,temp);
a[cnt]='\0';
}
void Remove_Minus(char a[],int n){ //去除“-”减号
char temp[1000];
int cnt=0;
for(int i=0;i<n;i++){
if(a[i]!='-'){
temp[cnt]=a[i];
cnt++;
}
}
strcpy(a,temp);
a[cnt]='\0';
}
int Change_SymboltoNum(char c){
int num;
switch (c){
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
num=c-87;
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
num=c-55;
break;
default: //剩余都是0~9,直接default处理了,小技巧
num=c-48;
break;
}
return num;
}
int main(){
char arr[1000]; //一并读入,并计算长度
gets(arr);
for(int i=0;;i++){
if(arr[i]=='#'){
arr[i]='\0';
break;
}
}
int len_arr=strlen(arr);
Remove_InvalidSympol(arr,len_arr); //筛去无效字符,并更新长度
len_arr=strlen(arr);
int isMinus=0;
if(arr[0]=='-'){ //判断正负,添加负号(X)
isMinus=1; //判断正负,做记号(√)
}
Remove_Minus(arr,len_arr); //筛去“-”,并更新长度
len_arr=strlen(arr);
int decimal_num=0; //Decimal十进制 转化
for(int i=len_arr-1;i>=0;i--){
int each=Change_SymboltoNum(arr[i]); //顺序对应,小坑
decimal_num+=pow(16,len_arr-i-1)*each;
}
if(decimal_num!=0&&isMinus){ //大坑!!没有“-0”一说!!需判断
printf("-");
}
printf("%d",decimal_num);
return 0;
}
收获:
1.去除无效字符,脑子太直了,完全可以用>,<解决
a>='0' && a<='9'
a>='a' && a<='f'
a>='A' && a<='F'
2.不用查ASCII码,直接:
c-‘a’
c-‘A’
3.逐个读入字符:
while(scanf("%c",&a),a!='#'){
/* code */
}
4.大坑!!没有“-0”一说!!需判断
改进版:
(待更)