输入一个以#结束的字符串,本题要求滤去所有的非十六进制字符(不分大小写),组成一个新的表示十六进制数字的字符串,然后将其转换为十进制数后输出。如果在第一个十六进制字符之前存在字符“-”,则代表该数是负数。
输入格式:
输入在一行中给出一个以#结束的非空字符串。
输出格式:
在一行中输出转换后的十进制数。题目保证输出在长整型范围内。
输入样例:
+-P-xf4+-1!#
输出样例:
-3905
思路:本题的要求是先定义一个以'#'结束的字符串,再去除所有与十六进制相关的字符后将其转换成十进制数,若在第一个十六进制字符前面出现了'-',则代表最终所求的十进制数为负数。
那么我们首先可以定义一个字符串,这里注意此字符串中可能会出现如空格之类的字符,所以需要用到scanf("%[^\n]s",xx);来输入字符串数组,为的是让scanf读到换行符为止,以确保能成功读入换行符前所有的字符。
此外我们还需要知道那些字符是与十六进制相关的,在十六进制中通常用'0'-'9'代表数字上的0-9,用'a' - 'f'或者'A' - 'F'代表10-15(因为题中表示不区分大小写)。所以我们可以用一个if判断句来将这三种情况用 || 连接起来。
这里要特别注意:'-'出现的位置时第一个十六进制字符前面,而不是一定要在第一个十六进制字符左边。
详细代码如下:
#include <stdio.h>
#include <stdbool.h>
int main(){
char arr[1000];
long long result = 0;
long long temp;
scanf("%[^\n]s",arr);
bool negetive_sign = false;
bool find_sixteen = false;// 用布尔类型来判断是否找到'-',以及十六进制字符
for(int i = 0;arr[i] != '#';i ++){
//如果在找到第一个十六进制字符前找到了'-',则将其变为true
if(arr[i] == '-'){
if(!find_sixteen){
negetive_sign = true;
}
continue;
}
if((arr[i] >= 'A' && arr[i] <= 'F') || (arr[i] >= 'a' && arr[i] <= 'f') || (arr[i] >= '0' && arr[i] <= '9')){
find_sixteen = true;//找到第一个十六进制字符,将其变为true
if(arr[i] > 'A' && arr[i] <= 'Z'){
temp = arr[i] - 'A' + 10;//将字符转换成数字
}
else if(arr[i] >= 'a' && arr[i] <= 'z'){
temp = arr[i] - 'a' + 10;
}
else{
temp = arr[i] - '0';
}
result = result * 16 + temp;//将十六进制数转换成十进制
}
}
if(negetive_sign){
result = -result;
}
printf("%lld",result);
return 0;
}
逐步分析:
for(int i = 0;arr[i] != '#';i ++){
if(arr[i] == '-'){
if(!find_sixteen){
negetive_sign = true;
}
continue;
}
用一个for循环,如果arr[i] 不等于'#' ,则一直执行下去,接着判断arr[i]是否是'-',如果是则进入下一个if判断句,if(!find_sixteen)的意思是如果在没有找到第一个十六进制字符之前发现了'-',则满足条件,让negetive_sign等于true。
if((arr[i] >= 'A' && arr[i] <= 'F') || (arr[i] >= 'a' && arr[i] <= 'f') || (arr[i] >= '0' && arr[i] <= '9')){
find_sixteen = true;
if(arr[i] > 'A' && arr[i] <= 'Z'){
temp = arr[i] - 'A' + 10;
}
else if(arr[i] >= 'a' && arr[i] <= 'z'){
temp = arr[i] - 'a' + 10;
}
else{
temp = arr[i] - '0';
}
result = result * 16 + temp;
}
}
if(negetive_sign){
result = -result;
}
用两个或运算符将三个判断十六进制字符的条件连接起来,满足其中一个即满足条件,并且令find_sixteen的值为true。接着再分别对三个条件进行判断,再将字符转换成数字。
这里需要细讲一下为什么这个操作会将字符转换成数字了,若字符是'0' - '9',则用字符减去'0'则会得到对应的数字,这个无需多说。主要是面对字符是'a' - 'f'和'A' - 'F'的情况,这两种情况思路一样就以前者为例,arr[i] - 'a'的意思其实是arr[i]与'a'在ascii骂上的相对位置,比如'b' - 'a' = 1(由他们对应的ascii码相减所得),表示b在a的右侧,+10则将其转换成了数字,即十六进制中用b或者B表示11这个数字。
最后将答案输出即可。
本人刚学习c语言不久,如果不正确,或逻辑不通的地方还望指正,本人一定虚心学习!
谢谢大家观看!