问题 D: 十六进制加
时间限制: 1 Sec 内存限制: 128 MB
提交: 486 解决: 231
[提交][状态][讨论版]
题目描述
在十六进制表示中,ABCDEF用于表示十进制的10、11、12、13、14、15
现输入两个表示十六进制整数的字符串,请计算它们相加的结果,用十进制表示。
如果输入的字符串包含非十六进制的编码,无需计算,直接输出-1表示错误
十六进制转十进制举例,例如十六进制数23A4共有4位数,从右往左数,含义如下:
数字2在第4位,对应16的3次方
数字3在第3位,对应16的2次方
数字A表示十进制的10,它在第2位,对应16的1次方
数字4在第1位,对应16的0次方
因此23A4 = 216^3 +316^2 + 1016^1 + 416^0
= 2*4096 + 3*256 + 10*16 + 4*1
= 9124
所以十六进制的23A4转成十进制是9124
输入
第一行输入T表示有T个测试实例
第二行输入第一个十六进制整数的字符串(长度不超过5)
第二行输入第二个十六进制整数的字符串(长度不超过5)
依此类推输入下一个实例
输出
输出相加的结果,用十进制表示
样例输入
3
A8
9F
3322Q
44455
11111
22222
样例输出
327
-1
209715
提示
注意十六进制的每个位表示十六的不同次幂
之前第一次写写的很麻烦,就大概是先判断两个字符串是否满足合法的十六进制数然后再做加法
代码如下:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
bool isok(string x) //判断是不是合法字符串
{
int n=x.length();
for(int i=0;i<n;i++)
if( !((x[i]>='0' && x[i]<='9') || (x[i]>='A' && x[i]<='F')))
return false;
return true;
}
int main()
{
string str1,str2;
char* str="0123456789ABCDEF";
int T;
cin>>T;
while(T--)
{
cin>>str1>>str2;
string result;
bool tag=true;
if(str1.length()<str2.length()) //判断哪个字符串更长
tag=true;
else tag=false;
if( isok(str1) && isok(str2) ) //调用函数来判断是不是合法字符串
{
int maxlen=max(str1.length(),str2.length());
int minlen=min(str1.length(),str2.length());
int yushu=0;
reverse(str1.begin(),str1.end()); //反转字符串容易计算
reverse(str2.begin(),str2.end());
for(int i=0;i<maxlen;i++)
{
int temp=0;
if(i<minlen)
{
if(isalpha(str1[i]))
temp+=toupper(str1[i])-'A'+10;
else temp+=str1[i]-'0';
if(isalpha(str2[i]))
temp+=str2[i]-'A'+10;
else temp+=str2[i]-'0';
result+=str[(temp+yushu)%16];
yushu=(temp+yushu)/16; //这一块其实可以用函数因为代码差不多..
}
else
{
if(tag)
{
if(isalpha(str2[i]))
temp+=str2[i]-'A'+10;
else temp+=str2[i]-'0';
result+=str[(temp+yushu)%16];
yushu=(temp+yushu)/16;
}
else
{
if(isalpha(str1[i]))
temp+=str1[i]-'A'+10;
else temp+=str1[i]-'0';
result+=str[(temp+yushu)%16];
yushu=(temp+yushu)/16;
}
}
}
if(yushu!=0)
result+=str[yushu%16];
int x=0;
int temp2=1;
for(int i=0;i<result.length();i++,temp2*=16) //十六进制转十进制
{
if(isalpha(result[i]))
x+=(result[i]-'A'+10)*temp2;
else x+=(result[i]-'0')*temp2;
}
cout<<x<<endl;
}
else cout<<-1<<endl;
}
return 0;
}
后面又想了想,其实可以考虑使用字符串流输入能减少代码量
下面是代码:
#include <iostream>
#include <sstream>
using namespace std;
bool isok(string x)
{
int n=x.length();
for(int i=0;i<n;i++)
if( !((x[i]>='0' && x[i]<='9') || (x[i]>='A' && x[i]<='F')))
return false;
return true;
}
int main()
{
int T;
cin>>T;
while(T--)
{
string s1,s2;
cin>>s1>>s2;
int a,b;
if(isok(s1) && isok(s2))
{
stringstream ss(s1);
stringstream ss1(s2);
ss>>hex>>a;
ss1>>hex>>b;
cout<<a+b<<endl;
}
else cout<<-1<<endl;
}
return 0;
}
感觉第一个代码写的挺失败以后再试试能不能缩减代码…写的略长