原创作品 转载请注明出处http://blog.csdn.net/always2015/article/details/45791789
思路:
一看到这一道题我的直接思维是:把十六进制转化成十进制,然后十进制转化成十六进制输出,但是发现这样做有点绕,实现起来是有点难度的,最初也是用了这一种方式做了,花了比较长的时间,但是也AC了。。。下面首先我先讲解我用上述方法的解题思路,然后再讲解另一个简单的方法。其实计算机自己就会执行十六进制的运算,只不过的不能直接输出题目所要求那样的负数,不信的话自己也可以试试复数的十六进制输出结果。所以当结果为负数时候,为了得到题目所要求的需要自己转化。。。
题上说的A 和B 的长度不超过15,因为A和B 是十六进制数,如果长度不考虑正负号的话,一个数字表示4位二进制数,所以A 、B的位数是60位,所以定义A、B时,要定义为64位。当然如果考虑正负号的话,A、B含有的的数字最多为14个,这时,A、B的位数为56位,当然还要定义成64位的。。然后,把A和B相加,当然还是十六进制的数,赋值给B,判断B是不是负数,如果是负的,需变成正的,输出时,添个负号即可。。。所以在本代码中定义A,B两个数需要时long long 型或者__int64,对于long long 和__int64的区别可以查看http://blog.csdn.net/shiwei408/article/details/7463476,在这道题中两个都可以,但是在最后输出时候,long long 格式输出需要写成“%llX”而__int64需要写成“%I64X”。
还有注意一个细节:%X 或者是%x,可以直接输出十六进制的数字(大写的X,则对应大写的输出,例如A、B、…..。同理,小写的x对应小写的输出),我的第一种AC代码如下:
#include <iostream>
#include<string>
#include<math.h>
#include<stdio.h>
#include<string.h>
using namespace std;
int main(void)
{
string a,b;
__int64 int_a=0,int_b=0;
int a_length,b_length,a_symbol,b_symbol;
while(cin>>a>>b)
{
//取符号
if(a[0]!='-')
a_symbol=1;
else
a_symbol=-1;
if(b[0]!='-')
b_symbol=1;
else
b_symbol=-1;
//获取长度
a_length=a.size();
b_length=b.size();
//将a转换为十进制
for(int i=0; i<a_length; i++)
{
//碰到符号就跳过
if(a[i]=='-'||a[i]=='+')
continue;
//当大于10的十六进制时候的转化
if(a[i]>='A'&&a[i]<='F')
int_a+=((a[i]-'A')+10)*(__int64)pow(16.0,a_length-i-1);
else if(a[i]>='a'&&a[i]<='f')
int_a+=((a[i]-'a')+10)*(__int64)pow(16.0,a_length-i-1);
else//小于10的十六进制的转化
int_a+=(a[i]-'0')*(__int64)pow(16.0,a_length-i-1);
}
//将b转换为10进制
for(int j=0; j<b_length; j++)
{
//碰到符号就跳过
if(b[j]=='-'||b[j]=='+')
continue;
//当大于10的十六进制时候的转化
if(b[j]>='A'&&b[j]<='F')
int_b+=((b[j]-'A')+10)*(__int64)pow(16.0,b_length-j-1);
else if(b[j]>='a'&&b[j]<='f')
int_b+=((b[j]-'a')+10)*(__int64)pow(16.0,b_length-j-1);
else//小于10的十六进制的转化
int_b+=(b[j]-'0')*(__int64)pow(16.0,b_length-j-1);
}
//求a,b的和运算
__int64 d=a_symbol*int_a+b_symbol*int_b;
//注意结果为负数的时候所要输出结果和计算机计算结果有不同
if(d>=0)
printf("%I64X\n",d);
else
printf("-%I64X\n",-d);
//重新初始化
int_a=0;
int_b=0;
}
return 0;
}
确实上面的这个方法有点繁琐。下面我来介绍另一种简单方法。其实在计算机中是可以进行十六进制的加减运算的,所以这就可以直接输入十六进制进行运算,所需要注意的问题和上述的一样,下面我就先来看C语言下的AC代码:
#include<stdio.h>
int main()
{
__int64 A,B;
while(scanf("%I64X %I64X",&A,&B)!=EOF)
{
B=A+B;
if(B>=0)
printf("%I64X\n",B);
if(B<0)
{
B=-B;
printf("-%I64X\n",B);
}
}
return 0;
}
而且C++也是可以这么写的:c++中一般我们的输入都是十进制的,要输入其它类型的数据:(n是申明的变量)
cin>>oct>>n; 输入八进制
cin>>hex>>n; 输入十六进制.
AC代码如下:
#include <iostream>
#include<stdio.h>
using namespace std;
int main()
{
long long A,B;
while(cin>>hex>>A>>B)
{
B=A+B;
if(B>=0)
printf("%I64X\n",B);
else
{
B=-B;
printf("-%llX\n",B);
}
}
return 0;
}
看了上述代码可能会有人有疑问:C++最后输出也可以用C++的格式输出啊如:
cout.setf(ios::showbase);//设置输出时的基数符号
cout.unsetf(ios::dec);//终止10进制的格式设置,因为编译器默认的10进制输出
cout.setf(ios::hex);//y设置以16进制输出
cout<<a<<endl;//16进制输出a
上述确实能输出十六进制a,但是他的输出格式为:0x…,前面带有十六进制标志的,不是我们所要的输出结果,不过也可以转化,在这里我就直接使用C的格式输出了。
比较这几种方式的,当然是最后两种最简单了。第一种可以让你更加清楚理解十六进制的与十进制的转换。