题目:
输入一个以#结束的字符串,本题要求滤去所有的非十六进制字符(不分大小写),组成一个新的表示十六进制数字的字符串,然后将其转换为十进制数后输出。如果在第一个十六进制字符之前存在字符“-”,则代表该数是负数。
输入格式:
输入在一行中给出一个以#结束的非空字符串。
输出格式:
在一行中输出转换后的十进制数。题目保证输出在长整型范围内。
输入样例:
+-P-xf4+-1!#
输出样例:
-3905
思路:
读取字符串
用arr1[](字符型)来读取字符串。注意题目要求以#结尾,则可以用scanf("%[^#]",arr);来控制。
提取十六进制字符
用arr2[](字符型)来保存arr1[]的十六进制字符。用循环进行遍历,内层使用选择结构用ASCII码值来控制条件为数字,A-F,a-f。ps:注意在arr2结尾加上'\0',表示截止。
进制转换
题目中设计到了数字和大小写字母,要分开讨论,并且其字符形式是字符,进行计算时要加以注意。用num=0;来计算各个位上的总和。用n=0;来表示进制转换时的16的n次幂
外层依然用循环来遍历arr2上的各个位数。但要控制其从最低位开始(读取时从最高位开始读取),需要设置起始值为(strlen(arr2)-1),条件是i>=0,迭代条件是i--,n++(后面会用到n)
内层用选择分支分别对数字,大写字母,小写字母分类讨论。数字一般情况处理,字母以大写字母为例:该位置上的十进制转化式(以C为例)为 num=num+('C'-'A'+10)*pow(16,n);'C'-'A'部分表示该字母与A的距离,而但凡是字母则表示其>=10所以需要+10。
负号检测
我们可以在最后输出num的时候进行判断是否要取绝对值。题目要求:如果在第一个十六进制字符之前存在字符“-”,则代表该数是负数。所以我们可以在最开始number=1,如果一旦检测到了十六进制字符就使number=0,表示已经读取过了十六进制字符。我们用flag=1来标记是否要取绝对值在确保在number=1的同时,如果同时读取到了'-',就让flag=0;最后输出的时候遍输出其绝对值。反之。。。
代码:
# include<stdio.h>
# include<math.h>
int main(){
char arr1[99];
scanf("%[^#]",arr1);
char arr2[99],j=0;
int flag=1,count=0,number=0;
for(int i=0;arr1[i]!='\0';i++){
if(arr1[i]=='-'&&number==0) {
flag=0;
}
if(arr1[i]>=48&&arr1[i]<=57||arr1[i]>=65&&arr1[i]<=70||arr1[i]>=97&&arr1[i]<=102){
arr2[j]=arr1[i];
j++;
count++;
number=1;
}
}
int num=0,n=0;
for(int i=count-1;i>=0;i--,n++) {
if(arr2[i]>=48&&arr2[i]<=57) {
num=num+(arr2[i]-'0')*pow(16,n);
}else if(arr2[i]>=65&&arr2[i]<=70) {
num=num+(arr2[i]-'A'+10)*pow(16,n);
}else if(arr2[i]>=97&&arr2[i]<=102) {
num=num+(arr2[i]-'a'+10)*pow(16,n);
}
}
if(flag==1) {
printf("%d",num);
}else {
printf("%d",-num);
}
return 0;
}
标签:字符,&&,十六进制,number,PTA,C语言,arr2,arr1,十进制
From: https://blog.csdn.net/2401_87626632/article/details/143713886